Gym - 102770C(字典树)

题目巨长,题意难厘清

可以用map过

const int maxn = 1e3 + 10;
int t, n, q, tot, l;
ll w, ans;
char s[maxn][maxn];
char tmp[maxn];
unordered_map<string, int> mp;

void init() {
	mp.clear();
	tot = 0; ans = 0;
}

int main() {//map可以998ms卡过,unorderde_map 770ms
	t = rd();
	while (t--) {
		init();
		n = rd(); q = rd();
		for (int i = 0; i < n; ++i)	scanf("%s", s[i]);
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < n; ++j) {
				if (s[i][j] == '#') {
					if (l) { tmp[l] = '\0'; mp[tmp] ++; l = 0; tot++; }
				}
				else
					tmp[l++] = s[i][j];
			}
			if (l) { tmp[l] = '\0'; mp[tmp] ++; l = 0; tot++; }
		}
		for (int j = 0; j < n; ++j) {
			for (int i = 0; i < n; ++i) {
				if (s[i][j] == '#') {
					if (l) { tmp[l] = '\0'; mp[tmp] ++; l = 0; tot++; }
				}
				else
					tmp[l++] = s[i][j];
			}
			if (l) { tmp[l] = '\0'; mp[tmp] ++; l = 0; tot++; }
		}

		while (q--) {
			scanf("%s %lld", tmp, &w);
			int tt = mp[tmp];
			ans += w * tt;
			tot -= tt;
		}
		if (!tot)	printf("%lld\n", ans);
		else	puts("-1");
	}
}
const int maxn = 2e6 + 10;
int trie[maxn][26], c[maxn];
char s[1010][1010];
int t, n, q, root = 0, tot = 0, num;
bool flag = 0;
ll ans = 0, w;

void init_trie() {
	for (int i = 0; i <= tot; ++i) {
		c[i] = 0;
		for (int j = 0; j < 26; ++j)	trie[i][j] = 0;
	}
	tot = 0;
	num = 0;
}

void insert(char* s) {
	int rt = root;
	int len = strlen(s);
	for (int i = 0; i < len; ++i) {
		int id = s[i] - 'a';
		if (id < 0) {//'#'
			if (rt != 0) {
				c[rt] ++;
				num++;
			}
			rt = root;
			continue;
		}
		if (trie[rt][id] == 0)	trie[rt][id] = ++tot;
		rt = trie[rt][id];
	}
	if (rt != 0) {
		c[rt] ++;//统计出现过几次
		num++;
	}
}

int find(char* s) {
	int rt = root;
	int len = strlen(s);
	for (int i = 0; i < len; ++i) {
		int id = s[i] - 'a';
		if (trie[rt][id] == 0)
			return 0;
		rt = trie[rt][id];
	}
	return c[rt];
}

char ch[maxn];
int main() {//正解字典树,440ms
	t = rd();
	while (t--) {
		init_trie();
		n = rd(); q = rd();
		for (int i = 0; i < n; ++i)	scanf("%s", s[i]);
		for (int i = 0; i < n; ++i) insert(s[i]);
		for(int i = 0; i < n; ++ i)
			for (int j = 0; j < i; ++j) {
				char tmp = s[i][j];
				s[i][j] = s[j][i];
				s[j][i] = tmp;
			}
		
		//for (int i = 0; i < n; ++i)	puts(s[i]);
		for (int i = 0; i < n; ++i)	insert(s[i]);

		ans = 0;
		while(q--) {
			scanf("%s %lld", ch, &w);
			int tmp = find(ch);
			ans += w * (ll)tmp;
			num -= tmp;
		}
		if (num)	puts("-1");
		else { write(ans); puts(""); }
	}
}

posted @ 2020-10-27 15:55  wansheking  阅读(126)  评论(0)    收藏  举报