#include <cstdio> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <vector> #include <cstring> #define INF 100000000 using namespace std; int ans[30]; int a[30]; int d[(1<<20)+10]; int fun(int dp){ if(dp == 0) { return d[0] = 0; } if(d[dp] != -1) { return d[dp]; } d[dp] = 0; for(int i = 2; i <= 20;i++){ int state = dp; if(state & (1 << (i-1))){ for(int j = 2;j <= 20;j++){ if(!(state&(1 <<(j-1)))){ for(int k = 1;k * i <= 20;k++){ for(int w = 1;k * i + w * j <= 20;w++ ){ int q = k * i + w *j; if(state&(1 << (q-1))){ state ^= (1 <<(q-1)); } } } } } int k = i; while(k <= 20){ if(state&(1 << (k-1))){ state ^= (1 <<(k-1)); } k+=i; } d[dp] |= !fun(state); } } return d[dp]; } int main(){ int n; int q = 1; memset(d,-1,sizeof(d)); while(scanf("%d",&n),n){ int dp = 0; for(int i = 0;i < n;i++){ scanf("%d",&a[i]); dp ^= (1 << (a[i]-1)); } memset(ans,0,sizeof(ans)); for(int i = 0;i < n;i++){ int state = dp; //寻找他对手的可能的状态 for(int j = 2;j <= 20;j++){ if(!(state&(1 <<(j-1)))){ for(int k = 1;k * a[i] <= 20;k++){ for(int w = 1;k * a[i] + w * j <= 20;w++ ){ int g = k * a[i] + w *j; if(state&(1 << (g-1))){ state ^= (1 <<(g-1)); } } } } } int k = a[i]; while(k <= 20){ if(state&(1 << (k-1))){ state ^= (1 <<(k-1)); } k += a[i]; } ans[a[i]] = !fun(state);//他的状态取决于他对手是否存在有一个必输态 } queue<int> que; for(int i = 2;i <= 20;i++){ if(ans[i] == 1){ que.push(i); } } printf("Test Case #%d\n",q++); if(!que.empty()){ cout << "The winning moves are:"; while(!que.empty()){ cout <<" "<< que.front(); que.pop(); } cout << endl; } else{ cout << "There's no winning move." << endl; } cout << endl; } return 0; }
原文地址:http://blog.csdn.net/qq_24667639/article/details/45539995