3895: 取石子
Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 318 Solved: 159
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
Sample Output
哈哈:O(1)的算法第一
总体模型:
设有n堆石子,sum为所有石子个数,那么最大操作数sg = sum+n-1
很显然最后面对sg=0的那个人失败,当前有三种操作:
①合并两堆石子:sg = sg-1
②从某一堆取走1个石子,取完之后那堆石子还有剩余:sg = sg-1
③某一堆石子只剩下一个,取走:sg = sg-2
考虑特殊情况:
如果不存在只有1个石子的石子堆,且sg为奇数,那么先手的Alice一定可以避免让Bob有机会执行上面的第③种操作
也就是如果某堆石子个数为2个,那么Alice绝对不会去取这一堆
这样每到Bob时sg就为偶数,显然Alice必胜,同理初始sg为偶数Alice必败
实际情况:
可能存在只有1个石子的石子堆
假设只有1个石子的石子堆有且只有1堆,那么Alice有两种操作:①将这堆石子和其它堆合并;②取走这个石子
可以发现无论Alice选操作①还是②都会使局面变为上面那种特殊情况,但是!两个操作的sg的奇偶结果不同
也就是先手的Alice可以控制局面从而必胜
我们再假设只有1个石子的石子堆有且只有2堆,那么Alice为了防止必败,一定要将这两堆石子合并成一个有两个石子的石子堆,这个时候仍然是上面的特殊情况,根据特殊情况判断胜负即可
……
以此类推,可以得出结论:
如果只有1个石子的石子堆为奇数堆,那么Alice必胜,否则就直接按上面的特殊情况进行处理
但是到这里还有一种情况没有判断:
全是只有一个石子的石子堆(即{1,1,…,1}):
对于{1}Alice必胜就不说了,对于{1,1}Alice只要将两堆石子合并成{2},Alice仍然必胜
{1,1,1}时Alice只能合并其中两堆,这样局面会变为{2,1},Bob只要把那个"1"拿走就必胜,所以Alice必败
……
以此类推,如果堆数不是3的倍数,那么Alice必胜,否则Alice必败
当然还有当前情况生成局面{2,1,1,…,1},就看只有1个石子的石子堆数是不是3的倍数,判别方法和上面一样
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[55];
int main(void)
{
int T, n, i, b, c;
scanf("%d", &T);
while(T--)
{
b = 0, c = -1;
scanf("%d", &n);
for(i=1;i<=n;i++)
{
scanf("%d", &a[i]);
if(a[i]==1) b++;
else c += a[i]+1;
}
if(c==-1 || b==n-1 && c==2)
{
if(b%3==0) printf("NO\n");
else printf("YES\n");
}
else
{
if(c%2 || c%2==0 && b%2) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}