int res = 0; while (n--) { array<bool, 25> a{}; while (m--) { cin >> x; a[x] = 1; } vector<int> b; int tot = 0; for (int i = 1; i <= 20; i++) { if (!a[i]) { b.push_back(tot); tot = 0; } else { tot++; } } reverse(b.begin(), b.end()); for (int i = 0; i < b.size(); i += 2) { res ^= b[i]; } } if (res) cout << "YES" << endl; else cout << "NO" << endl;
E. 真正的签到游戏 HDU-1730
游戏在一个 n 行 m 列的棋盘上进行,每行有一个黑子和一个白子。执黑的一方先行,每次玩家可以移动己方的任何一枚棋子到同一行的任何一个空格上,但不许越过该行的敌方棋子。双方轮流移动,直到某一方无法行动为止,不能操作者败。
对于每一行,最终态为黑白棋子距离为 0,中间若先手打破该状态,后手必有操作可以恢复到该状态,如此反复。因此只关心黑白棋子距离。依据 SG 定理,每行黑白棋子距离的 Nim 和不为 0 先手胜。
constint N = 1e6 + 8; int trie[N][26]; int pcnt = 0;
voidinsert(string& s){ int p = 0; for (auto c : s) { if (trie[p][c - 'a'] == -1) trie[p][c - 'a'] = ++pcnt; p = trie[p][c - 'a']; } }
intdfs(int n){ int sum = 0; int ans = 0; for (int i = 0; i < 26; i++) { if (trie[n][i] == -1) continue; else { sum++; int res = dfs(trie[n][i]); ans |= res ^ 3; } } if (sum == 0) return2; // 叶子节点 elsereturn ans; }
//ans = 1 win //ans = 2 lost //ans = 3 win or lost //ans = 0 do not know
intmain(){ int n, k; string s; cin >> n >> k; memset(trie, -1, sizeof trie); for (int i = 1; i <= n; i++) { cin >> s; insert(s); } int ans = dfs(0); if (ans == 1) { if (k & 1) { cout << "First" << endl; } else { cout << "Second" << endl; } } elseif (ans == 2 || ans == 0) { cout << "Second" << endl; } else { cout << "First" << endl; } return0; }
I. 巧克力游戏 -HDU 3544
给 n 块巧克力,第 i 块是 nimi,Alice 只能垂直切,Bob 只能横切。
设 HP(n,m) 表示 nm 的矩形对 Alice 的可切割次数的贡献,负数代表 Bob 的贡献,如果所有 ∑HPi>0 ,Alice 必赢, ∑HPi⩽0 ,Bob 必赢。
对于 HP(i,j) 的计算我们有如下法则
n∗1 的矩形贡献为 n−1;
1∗m 的矩形贡献为 −(m−1);
n×n 的矩形对 HP 的贡献为零,因为如果你首先下手切,都会给对手更多的机会,如果你能赢,你不会切这个,如果你输,那么切了这个你还会输;
n×(n+1) 的矩形与 3 的情况相同,对答案的贡献都是 0,首先下手都会给对手更多的机会;
贡献为零的有什么规律呢,我们发现原来是它们是 2k⩽n<2k+1 且 2k⩽m<2k+1;
n×2 的矩形对于 Alice 来说有贡献,我们每一次可以选择都切成 2×2,3×2 的矩形,这样不会给对手机会,自己还可以增加一次切的机会,Bob 也不会傻到切这个矩形,这样会给 Alice 更多机会,所以 n×2 的矩形,Alice 可以切 2n−1 次
int n; cin >> n; ll a = 0, b = 0; while (n--) { int x, y; cin >> x >> y; while (x > 1 && y > 1) { x >>= 1; y >>= 1; } if (y == 1) a += x - 1; if (x == 1) b += y - 1; } printf("Case %d: %s\n", Ti, a > b ? "Alice" : "Bob");