字典树变形 A

A - Gaby And Addition

 Gym - 101466A 

这个题目是一个字典树的变形,还是很难想到的。

因为这题目每一位都是独立的,不会进位,这个和01字典树求最大的异或和是不是很像。

知道这个了,就还比较好写了,不过要注意数组越界和超时问题。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <map>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
ll val[maxn * 20];
int trie[maxn * 20][10], tot;
ll f[20];
void init() {
	tot = 1;
	memset(trie[0], 0, sizeof(trie[0]));
	f[0] = 1;
	for (int i = 1; i <= 18; i++) f[i] = f[i - 1] * 10;
}
 
void insert(ll x) {
	int u = 0;
	// printf("x=%lld
", x);
	for (int i = 18; i >= 0; i--) {
		ll v = (x / f[i]) % 10;
		// printf("i=%d v=%lld
", i, v);
		if (trie[u][v] == 0) {
			memset(trie[tot], 0, sizeof(trie[tot]));
			val[tot] = 0;
			trie[u][v] = tot++;
		}
		// printf("u=%d v=%lld
", u, v);
		u = trie[u][v];
	}
	val[u] = x;
}
 
ll query_max(ll x) {
	int u = 0;
	for (int i = 18; i >= 0; i--) {
		ll v = (x / f[i]) % 10;
		bool flag = 0;
		for (int j = 9 - v; j >= 0; j--) {
			if (trie[u][j]) {
				flag = 1;
				u = trie[u][j];
				break;
			}
		}
		if (flag == 0) {
			for (int j = 9; j >= 9 - v + 1; j--) {
				if (trie[u][j]) {
					u = trie[u][j];
					break;
				}
			}
		}
	}
	return val[u];
}
 
ll query_min(ll x) {
	// printf("x=%lld
", x);
	int u = 0;
	for (int i = 18; i >= 0; i--) {
		ll v = (x / f[i]) % 10;
		// printf("i=%d v=%lld
", i, v);
		bool flag = 0;
		for (int j = 9 - v + 1; j <= 9; j++) {
			// printf("www u=%d v=%lld j=%d
", u, v,j);
			if (trie[u][j]) {
				u = trie[u][j];
				// printf("j=%d
", j);
				flag = 1;
				break;
			}
		}
		if (flag == 0) {
			for (int j = 0; j <= 9 - v; j++) {
				if (trie[u][j]) {
					u = trie[u][j];
					break;
				}
			}
		}
	}
	// printf("val=%lld
", val[u]);
	return val[u];
}
 
ll a[maxn];
 
ll check(ll a, ll b) {
	ll ans = 0;
	// printf("a=%lld b=%lld
", a, b);
	for (int i = 18; i >= 0; i--) {
		ans = ans * 10 + (a / f[i] % 10 + b / f[i] % 10) % 10;
	}
	return ans;
}
 
int main() {
	int n;
	init();
	scanf("%d", &n);
	ll maxs = 0, mins = inf64;
	for (int i = 1; i <= n; i++) {
		scanf("%lld", &a[i]);
		if(i!=1)
		{
			ll res1 = query_max(a[i]);
			ll res2 = query_min(a[i]);
			maxs = max(maxs, check(a[i], res1));
			mins = min(mins, check(a[i], res2));
		}
		insert(a[i]);
	}
	printf("%lld %lld
", mins, maxs);
	return 0;
}

  

原文地址:https://www.cnblogs.com/EchoZQN/p/11342521.html