题目大意
现有一个游戏,两个操作者轮流操作,每次操作需要选择一根柱子,首先至少需要该柱子上的一颗石子,然后可以对其剩下的石子任意进行分配,可以留在原柱子上,也可以放在其他有石子的柱子上,但不可以放在没有石子的柱子上。无法操作的人输,问先手是否有必胜策略。
题目分析
一开始是往SG函数的方面上想的,不过没什么思路,然后找规律,但菜鸡fhj找不出来,最后上网查,发现这道题就是找规律,不过要进行一定的推论。
首先分析n=1的情况,那么先手必胜,很显然。
n=2,此时如果两堆相等则后手只用和先手一样决策即可保证胜利,后手必胜。若不同则先手可以使其变成相等的两堆,先手必胜。
n=3,此时先手可以把该状态转换成两堆相等的石子状态,而且可以一步完成,所以依旧先手必胜。
n=4,此时两个人都不想自己取完后只有三个堆然后让对手华丽丽的胜利,所以就是能拖就拖,但如果到了4个堆都是1个的时候,还怎么拖呢,所以就是如何不会到了自己这就4个堆都只有一个石子?
联系前面的内容,然后就各种复杂的分析……发现,如果4个堆两两相等,那么先手必败,否则先手必胜。
……
所以规律:
1.当n为奇数的时候,先手必胜。
2.当n为偶数的时候,如石子堆两两相等,则先手必败,反之先手必胜。
这道题告诉我们,博弈论的题目最重要的解题方法就是:找规律!
#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[15];
inline void readi(int &x)
{
x=0; char ch=getchar();
while ('0'>ch||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
}
int main()
{
freopen("stone.in","r",stdin);
freopen("stone.out","w",stdout);
readi(n);
while (n)
{
for (int i=1;i<=n;i++) readi(a[i]);
if (n%2) printf("1\n");
else
{
sort(a+1,a+n+1); bool pd=true;
for (int i=1;i<n;i++)
if (i%2&&a[i]!=a[i+1]) {pd=false; printf("1\n"); break;}
if (pd) printf("0\n");
}
readi(n);
}
return 0;
}
Orz zzkksunboy
Orz zzkksunboy
Orz zzkksunboy
重要的事情……你懂得