给定一个序列,轮到谁,取出一个数k删除,并删除i*k(i=1,2,3,.....),
设k1为已经删除的数,同时删除k1*i+k*j,(i=1,2,3,.....;j同上 ),轮到谁没数删除时谁就输了。。
求先手取数 可以取那些数字 ,能保证获胜
#include<iostream>
#include <cstring>
#include <algorithm>
#include <iomanip>
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(0);
using namespace std ;
const int N =(1<<20)+20;
int f[N] ;
int b[N];
bool dfs(int s,int x){
s-=(1<<x) ;
for(int i=2;i+x<=20;i++)
if ( !((1<<i)&s) && (1<<(i+x))&s )
s-=(1<<(i+x));
if(f[s]>0) return 1 ;
if(f[s]<0) return 0;
for(int i=2;i<=20;i++)
if( (1<<i)&s&&!dfs(s,i)){
return f[s]=1 ;
}
f[s]=-1 ;
return 0 ;
}
signed main(){
int n,v,k,cnt=1,flag=0;
while (cin>>n&&n){
k=0;
if (flag)
cout<<endl;
memset(f,0,sizeof f);
f[0]=-1;
int ans=0;
for (int i=0;i<n;i++){
cin>>v;
ans+=(1<<v);
}
for (int i=2;i<=20;i++)
if(((1<<i)&ans)&&!dfs(ans,i))
b[k++]=i;
sort(b,b+k);
k=unique(b,b+k)-b;
cout<<"Test Case #"<<cnt++<<endl;
if (k)
{
cout<<"The winning moves are: ";
for (int i=0;i<k;i++)
cout<<b[i] << ((i==k-1)?"\n":" ");
}
else
cout<<"There's no winning move."<<endl;
flag=1;
}
return 0;
}
浙公网安备 33010602011771号