一開始看還以為是一道博弈的題目,再仔細看才發現并不是博弈,也不是很難。大致意思是:有n堆石子,第i堆有Ki個石子,每輪一方可以從任意堆中取出一個或多個石子,所有石子都被取光時,游戲也結束了,那個最后一輪拿走石子的人就是勝利者。問你有多少種方法使對方處于必敗的局面。題目并不難,是因為題目中已經告訴你了產生必敗局面的條件:如果所有堆的石子數的異或和為0,那么處于此局面的人就必敗。
因為每次只能從一個堆中取石子,所以只要對于每個堆i,先求出其他所有堆的異或和temp,再看0~Ki-1與這個異或和再進行異或是否為0,只要為0就得到一種勝利的方法。自己先是想枚舉0~Ki-1,與temp進行異或。后來感覺沒有必要,只要Ki>temp就可以了,因為若從堆i中取出x個石子,Ki-x異或temp==0 <==> Ki-x==temp,只要Ki>temp,就存在Ki-x==temp。
#include <cstdio>
#define PILE 1001
__int64 stone[PILE], test; //test為所有石子數的異或和
int piles;
bool Input ()
{
scanf("%d", &piles);
if ( piles == 0 )
return false;
int i;
for (i=0; i<piles; i++)
scanf("%I64d", &stone[i]);
return true;
}
void Solve ()
{
int i, ans;
__int64 temp;
test = 0;
ans = 0;
for (i=0; i<piles; i++)
test ^= stone[i];
if ( test != 0 )
{
for (i=0; i<piles; i++)
{
temp = test ^ stone[i]; //再與stone[i]做一次異或,相當于除stone[i]對其他所有堆的石子進行異或
if ( stone[i] > temp )
ans++;
}
}
printf("%d\n", ans);
}
int main ()
{
while ( Input() )
{
Solve();
}
return 0;
}