枚举第一步可能达到的状态,判断是否是必败态即可。
#include<cstdio> #include<set> #include<cstring> using namespace std; int SG[1001],a[1001],b[1001],n,m,all; int sg(int x) { if(SG[x]!=-1) return SG[x]; set<int>S; for(int i=1;i<=m;++i) { if(b[i]>x) break; S.insert(sg(x-b[i])); } for(int i=0;;++i) if(S.find(i)==S.end()) return SG[x]=i; } int main() { memset(SG,-1,sizeof(SG)); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); scanf("%d",&m); for(int i=1;i<=m;++i) scanf("%d",&b[i]); for(int i=1;i<=n;++i) all^=sg(a[i]); puts(all?"YES":"NO"); if(all) { for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { int t=0; for(int k=1;k<i;++k) t^=sg(a[k]); for(int k=i+1;k<=n;++k) t^=sg(a[k]); if(!(t^sg(a[i]-b[j]))) { printf("%d %d ",i,b[j]); return 0; } } } return 0; }