[COCI2020-2021#3] Vlak

[COCI2020-2021#3] Vlak

题意

Nina 和 Emilija 在玩游戏。

Nina 先手,两人轮流在纸上写下一个字母。

每个玩家写下字母后得到的单词必须是该玩家喜欢的歌曲中某个单词的前缀。

不能操作的玩家输,判断最后谁会赢。

思路

对每个玩家喜欢的歌曲建立字典树。

搜索每个玩家的操作,每次在两个字典树上移动。

最多把字典树的每个节点访问一遍,时间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 5;
struct Trie {
	int son[N][27], cnt = 1;
	void insert(string s) {
		int p = 1;
		for (auto c : s) {
			int num = c - 'a', &q = son[p][num];
			q = (!q ? ++ cnt : q), p = q;
		}
	}
} Nina, Emil;
int n, m;
bool dfs(int Np, int Ep, int state) {
	if (!state) {
		bool res = 0;
		for (int i = 0; i < 26; i ++) {
			if (!Nina.son[Np][i]) continue;			
			res |= !dfs(Nina.son[Np][i], Emil.son[Ep][i], !state);
		}
		return res;
	} else {
		bool res = 0;
		for (int i = 0; i < 26; i ++) {
			if (!Emil.son[Ep][i]) continue;
			res |= !dfs(Nina.son[Np][i], Emil.son[Ep][i], !state);
		}			
		return res;
	}
}
void solve() {
	cin >> n;
	for (int i = 1; i <= n; i ++) {
		string s; cin >> s;
		Nina.insert(s);
	}
	cin >> m;
	for (int i = 1; i <= m; i ++) {
		string s; cin >> s;
		Emil.insert(s);
	}
	bool ans = dfs(1, 1, 0);
	if (ans) cout << "Nina\n";
	else cout << "Emilija\n";
}
int main() {
	int T = 1;
//	cin >> T;
	while (T --)
		solve();
	return 0;
}
posted @ 2024-09-10 21:15  maniubi  阅读(4)  评论(0编辑  收藏  举报