您的位置:首页 > 其它

HDU 1907 John nim博弈变形 Anti-SG

2016-12-21 15:59 543 查看

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=1907

题意:

nim博弈,不过取最后一次的人失败,输出获胜的那个人

思路:

Anti−SG:

Anti−SG 游戏规定,决策集合为空的游戏者赢。

Anti−SG 其他规则与SG 游戏相同。

SJ定理:

对于任意一个 Anti−SG 游戏,如果我们规定当局面中所有的单一游戏的 SG 值为 0 时,游戏结束,则先手必胜当且仅当:

游戏的 SG 函 数不为 0 且游戏中某个单一游戏的 SG 函数大于1;

游戏的 SG 函数 为 0 且游戏中没有单一游戏的 SG 函数大于1。

设所有石子异或和为0时状态为T,不为0时状态为S,设只有一个石子的堆为孤单堆,否则为充裕堆。T状态下无充裕堆的状态记为T0,大于等于2个充裕堆的记为T2。根据上述定义可以定义S0,S1,S2。有结论如下:T0,S1,S2为必胜态,T2,S0为必输态。

[定理1]:S0态,即仅有奇数个孤单堆,必败。T0态必胜。

证明:S0态,其实就是每次只能取一根。每次第奇数根都由己取,第偶数根都由对方取,所以最后一根必己取。败。同理, T0态必胜

[定理2]:S1态,只要方法正确,必胜。

证明:若此时孤单堆堆数为奇数,把充裕堆取完;否则,取成一根。这样,就变成奇数个孤单堆,由对方取。由定理5,对方必输。己必胜

[定理3]:S2态不可转一次变为T0态。

证明:充裕堆数不可能一次由2变为0。得证

[定理4]:S2态可一次转变为T2态。

证明:由定理1,S态可转变为T态,态可一次转变为T态,又由定理6,S2态不可转一次变为T0态,所以转变的T态为T2态

[定理5]:T2态,只能转变为S2态或S1态。

证明:T态必然变为S态。由于充裕堆数不可能一次由2变为0,所以此时的T态不可能为S0态。命题得证。

[定理6]:S2态,只要方法正确,必胜.

证明:

方法如下:

1) S2态,就把它变为T2态

2) 对方只能T2转变成S2态或S1态

若转变为S2, 转向1)

若转变为S1, 这己必胜。

[定理7]:T2态必输。

证明:同6。

综上所述,必输态有: T2,S0 必胜态: S2,S1,T0.

#include <bits/stdc++.h>

using namespace std;

int main()
{
int t, n, a;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
int ans = 0;
bool flag = true;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a);
if(a > 1) flag = false;
ans ^= a;
}
if(flag) puts(ans ? "Brother" : "John");
else puts(ans ? "John" : "Brother");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: