题意
首先Alice先走,然后每次至少扔掉一个棋子,然后从该堆拿出任意的石子(>=0)进行任意的分配,任意的分配是指可以拿出一部分分给其他还剩有石子的堆(数目自己定),
谁拿最后一堆谁就赢
思路
模仿策略。
假设现在的场面是:剩余偶数堆,并且每一堆都可以找到一一对应的关系,关系中两个堆石子数目相等。即所有数目的堆都有偶数个。在这种情况下,后手只要模仿先手操作对应的堆,就一定能获得胜利,即后手必胜。
如果不是上述场面,必能在一个回合变成这样。如果堆数为奇数,则拿走最大的一堆,将其他堆配成对应。否则,将最大的一堆变成和最小一堆相等,然后配成对应。
这样的操作必定能够成功。证明:
将所有堆按石子数目从小到大排序,则最后一堆与第一堆之间的差值必定大于中间所有相邻堆的差值之和。
链接
http://poj.org/showmessage?message_id=172828
代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 12;
int n;
int A[maxn];
int main(){
while(scanf("%d", &n) == 1 && n){
for(int i = 0; i < n; ++i){
scanf("%d", A + i);
}
sort(A, A + n);
bool win = false;
for(int i = 1, cnt = 1; i < n; ++i){
if(A[i] == A[i-1]) ++cnt;
else{
if(cnt & 1){
win = true;
break;
}
cnt = 1;
}
}
if(win) puts("1");
else puts("0");
}
return 0;
}