Problem
游戏开始有四座塔,每座均由正方体叠成,所有正方体是黑色或者白色
玩家和轮流操作,每次选定一个正方体,将正方体及其以上正方体全部拿走
玩家只能选择白色正方体,玩家只能选择黑色正方体,不能操作者输
如果玩家无论先手或者后手都能赢,则称局面为
定义子局面为三塔局面即为,对于完整局面
如果对于任意塔,为时,均为
则称不劣于,给定和,判断是否不劣于
Solution
考虑一座塔的SN值,当塔为空时
如果塔包含一个白色正方体,则玩家L拥有可转移到的决策,
如果塔包含n个白色正方体,则
同理塔包含n个黑色正方体时
当塔包含n个白色正方体和顶端一个黑色正方体时,
如果包含n个白色正方体和顶端两个黑色正方体时,
在以上情况下在顶端再堆叠一个白色正方体,
结论就比较显然了,除去最底端的连续块,黑色方块,白色方块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <cstdio> #include <cstring> using namespace std; double getSN(int T[], int n) { double SN = 0; int i = 0; for (; i < n && T[i] == T[0]; i++) SN += T[i]; for (double k = 2; i < n; i++, k = k * 2) SN += T[i] / k; return SN; } const int N = 60; char s[N]; int T[N], d[3], Cas; int main() { scanf("%d", &Cas); for (int cas = 1; cas <= Cas; cas++) { scanf("%s%s", s, s); for (int i = 0; i < 3; i++) scanf("%d", &d[i]); double SN1 = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < d[i]; j++) { scanf("%s", s); T[j] = 2 * (s[0] == 'W') - 1; } SN1 += getSN(T, d[i]); } for (int i = 0; i < 3; i++) scanf("%d", &d[i]); double SN2 = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < d[i]; j++) { scanf("%s", s); T[j] = 2 * (s[0] == 'W') - 1; } SN2 += getSN(T, d[i]); } if (SN1 >= SN2) printf("Test %d: Yes\n", cas); else printf("Test %d: No\n", cas); } return 0; }
|