尼姆博奕:有N堆物品,其中第i堆有Pi个物品,每次从一堆里选出若干物品去掉(不能不取出物品),两个人轮流取物,谁不能继续取谁就先输或者赢了。
题目1:有n堆火柴,每次可以从任意堆拿出任意数量的火柴,谁拿走最后的谁就赢。
题目分析:我们将n堆火柴数异或。若结果非0,则先走的玩家赢
#include <iostream>
using namespace std;
int main() {
int n,ans,temp;
while(scanf("%d",&n) != EOF)
{
scanf("%d",&ans);
n--;
while(n--)
{
scanf("%d",&temp);
ans ^= temp;
}
if(ans)
printf("Yes/n");
else
printf("No/n");
}
return 0;
}
题目2:有n堆石子,两人轮流从任一堆中取出任意个石子(至少一个),最后一个取石子的人为赢家。问最后有多少种赢法?
题目分析:首先求n堆石子数异或后的结果t,若t=0,则输;接着,设第i堆石子的数目为a[i],若t+a[i]<a[i]则输,因此我们要统计出有多少堆的石子数大于t+a[i]。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1001;
int n,a[maxn]; //数组a存储每堆石子数,n是堆数
int main()
{
while(scanf("%d",&n)&&n)
{
int t=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
t^=a[i];
}
int ans=0; //统计赢得次数
for(int i=0;i<n;i++)
if((t^a[i])<a[i])
ans++;
printf("%d\n",ans);
}
return 0;
}