题目链接:http://codeforces.com/gym/101466/problem/A
题目:
题意:
给你n个数,重定义两个数之间的加法不进位,求这些数中两个数相加的最大值和最小值。
思路:
字典树。我们首先将前i-1为放入字典树中,然后在查询第i位时,我们去字典树中查询,对每一位进行寻找,找到满足题意的当前位的最大值和最小值,然后继续更新下一位,最后维护总的最大值和最小值即可。
代码实现如下:
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;;
typedef pair<int, int> pii;
typedef unsigned long long ull; #define lson i<<1
#define rson i<<1|1
#define lowbit(x) x&(-x)
#define bug printf("*********\n");
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define FIN freopen("D://code//in.txt", "r", stdin);
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e6 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; int n;
int le,root;
int arr[];
ll num, pw[]; struct node{
int nxt[];
void init(){
for(int i = ; i < ; i++) nxt[i] = -;
}
}T[*maxn]; void insert(ll x){
int now = root;
for(int i = ; i <= ; i++) {
arr[i] = x % ;
x /= ;
}
for(int i = ;i >= ; i--){
int num = arr[i];
if(T[now].nxt[num] == -){
T[le].init();
T[now].nxt[num] = le++;
}
now = T[now].nxt[num];
}
} ll search1(ll x){
int now = root, mx, idx;
ll res = ;
for(int i = ; i <= ; i++) {
arr[i] = x % ;
x /= ;
}
for(int i = ; i >= ; i--) {
mx = -, idx = -;
for(int j = ; j < ; j++) {
if(T[now].nxt[j] != - && (j + arr[i]) % > mx) {
mx = (j + arr[i]) % ;
idx = j;
}
}
now = T[now].nxt[idx];
res = res + mx * pw[i];
}
return res;
} ll search2(ll x){
int now = root, mx, idx;
ll res = ;
for(int i = ; i <= ; i++) {
arr[i] = x % ;
x /= ;
}
for(int i = ; i >= ; i--) {
mx = , idx = -;
for(int j = ; j < ; j++) {
if(T[now].nxt[j] != - && (j + arr[i]) % < mx) {
mx = (j + arr[i]) % ;
idx = j;
}
}
now = T[now].nxt[idx];
res = res + mx * pw[i];
}
return res;
} int main() {
le = ;
pw[] = ;
for(int i = ; i <= ; i++) pw[i] = pw[i-] * ;
T[].init();
scanf("%d", &n);
ll ans1 = INF, ans2 = -;
for(int i = ; i <= n; i++) {
scanf("%lld", &num);
if(i > ) {
ans1 = min(search2(num), ans1);
ans2 = max(search1(num), ans2);
}
insert(num);
}
printf("%lld %lld\n", ans1, ans2);
return ;
}