uva 10561 - Treblecross(Nim)
2014-08-05 23:38
423 查看
题目链接:uva 10561 - Treblecross
题目大意:n个格子排成一排,其中一些格子有'X',两个游戏者轮流操作,在格子中放X,如果此时出现连续3个X,则获胜。给出先手是否可以取胜,取胜方案的第一步该怎么走。
解题思路:一个X可以导致左右两个的两个格子都不能再放X,因为如果出现XX.、.XX、X.X,那么下一个人肯定胜利。所以对于长度为n的格子序列,g(x)=maxg(x−3),g(x−4)...g(2)XORg(n−7).
所以可以预先处理出g数组,然后对于给定的序列,枚举先手下的位置,判断这种情况下,后手是否为必败态。注意如果先手一步即可胜利要特殊考虑。
题目大意:n个格子排成一排,其中一些格子有'X',两个游戏者轮流操作,在格子中放X,如果此时出现连续3个X,则获胜。给出先手是否可以取胜,取胜方案的第一步该怎么走。
解题思路:一个X可以导致左右两个的两个格子都不能再放X,因为如果出现XX.、.XX、X.X,那么下一个人肯定胜利。所以对于长度为n的格子序列,g(x)=maxg(x−3),g(x−4)...g(2)XORg(n−7).
所以可以预先处理出g数组,然后对于给定的序列,枚举先手下的位置,判断这种情况下,后手是否为必败态。注意如果先手一步即可胜利要特殊考虑。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 200; int g[maxn+5], v[maxn+5]; int SG (int s) { memset(v, 0, sizeof(v)); for (int i = 1; i <= s; i++) { int t = 0; if (s - i - 2 >= 0) t ^= g[s-i-2]; if (i - 3 >= 0) t ^= g[i-3]; v[t] = 1; } int mv = -1; while (v[++mv]); return mv; } void init () { memset(g, 0, sizeof(g)); g[1] = g[2] = g[3] = 1; for (int i = 4; i <= 200; i++) g[i] = SG(i); } int n, len, pos[maxn+5]; char str[maxn+5]; bool check () { int pre = -3, ret = 0; for (int i = 0; i <= len; i++) { if (str[i] == 'X') { if (i - pre <= 2) return false; int l = max(i - pre - 5, 0); if (l) ret ^= g[l]; pre = i; } } int l = max(len - pre - 3, 0); if (l) ret ^= g[l]; return ret == 0; } bool judge () { n = 0; len = strlen(str); for (int i = 0; i < len; i++) { if (str[i] == '.') { str[i] = 'X'; if (check()) pos[n++] = i + 1; str[i] = '.'; } if (i && i < len - 1 & str[i-1] == 'X' && str[i+1] == 'X') pos[n++] = i + 1; if (i < len - 2 && str[i+1] == 'X' && str[i+2] == 'X') pos[n++] = i + 1; if (i >= 2 && str[i-1] == 'X' && str[i-2] == 'X') pos[n++] = i + 1; } return n; } int main () { init(); int cas; scanf("%d", &cas); while (cas--) { scanf("%s", str); printf("%s\n", judge() ? "WINNING" : "LOSING"); if (n) printf("%d", pos[0]); for (int i = 1; i < n; i++) printf(" %d", pos[i]); printf("\n"); } return 0; }
相关文章推荐
- 【UVA 10561】 Treblecross|博弈论|SG函数
- UVA 10561 - Treblecross(博弈SG函数)
- UVA 10561 - Treblecross(博弈SG函数)
- UVA - 10561 Treblecross (SG定理)
- UVa 10561 Treblecross (SG函数)
- UVA 10561 Treblecross 组合游戏/SG定理
- UVA - 10561 Treblecross (博弈数学&SG函数)
- uva 10561 Treblecross(博弈)
- UVA 10561 Treblecross
- UVa 10561 (SG函数 递推) Treblecross
- uva 10561 Treblecross (SG函数)
- uva10561 - Treblecross SG定理
- uva10561 - Treblecross
- [UVa 10561]Treblecross游戏
- uva-10561-nim
- Cross the Wall UVALive - 5097 (贪心+斜率dp)
- (SG博弈)uva 10561 - Treblecross
- Division Game UVA - 11859 (Nim)题解
- Cross the Wall UVALive - 5097 (贪心+斜率dp)
- uva 11534 - Say Goodbye to Tic-Tac-Toe(Nim和)