做这道题,我收获了很多……
对于二进制解起题来的方便和简洁感到震惊……
我要继续好好学习!!!o(≧v≦)o~~
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n,i,t,dp[1000010],s[25];
int kp(bool x[]){
int count=0;
for(int i=2; i<=20;i++,count<<=1){
if(x[i])
{
count|=1;
}
}
return count>>1;
}
int dfs(bool a[], int st){
bool aa[25];
memcpy(aa,a,24);
aa[st]=0;
for(int i=2; i+st<=20; i++)
{
if(!aa[i])
aa[i+st]=0;
}
int iid=kp(aa);
if(dp[iid]!=0){
if(dp[iid]>0) return 1;
else return 0;
}
for(int i=2;i<=20;i++){
if(aa[i]&& !dfs(aa,i)){
dp[iid]=1;
return 1;
}
}
dp[iid]=-1;
return 0;
}
int main(){
t=0;
bool a[31];
int id,x;
while(scanf("%d", &n)&&n!=0)
{
memset(a,0,sizeof(a));
for(i=0;i<n;i++)
{
scanf("%d",&x);
a[x]=1;
}
id=kp(a);
int sum=0;
for(i=2;i<=20;i++)
{
if(a[i]&& !dfs(a,i))
{
s[sum++]=i;
}
}
t++;
printf("Test Case #%d\n",t);
if(sum==0){dp[id]=-1;printf("There's no winning move.\n\n");}
else
{
printf("The winning moves are:");
for(i=0;i<sum;i++)
{
printf(" %d",s[i]);
}
printf("\n\n");
}
}
return 0;
}