poj 2975
nim。
先把每堆中的数按位异或,得到一个数temp。然后把temp和每一堆中的石子数按位异或得到m,如果num[i]>m,则可以从这堆中取走num[i]-m个石子,使之成为胜局;否则不能从这堆中取子使之成为胜局。
现在解释原因。设其中任意一堆的数量为a,其它堆异或和为A,所有堆中的数量异或和为b,则a^A==b。已知a和b,可以求出A==a^b。而这个A,就是在a中取完石子后要剩下的石子数量,因为只有当取完子后剩下的数量为A,才能使得a^A==b。
代码:
#include<iostream> #include<fstream> using namespace std; long long a[1001]; void read(){ // ifstream cin("in.txt"); int i,j; int n; long long k; while(1) { cin>>n; if(n==0) return ; cin>>a[1]; k=a[1]; for(i=2;i<=n;i++) { cin>>a[i]; k^=a[i]; } if(k==0) { cout<<0<<endl; } else { int ans=0; for(i=1;i<=n;i++) if((k^a[i])<a[i]) ans++; cout<<ans<<endl; } } } int main(){ read(); return 0; }