取石子游戏
sol:求出SG值很简单,第一问答案很简单
第二问就是在自己取过以后给对方留一个必败态即可
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') const int N=15,L=1005; int n,m,A[N],B[N]; int SG[L],Mark[L]; int main() { int i,j,ans=0; R(n); for(i=1;i<=n;i++) R(A[i]); R(m); for(i=1;i<=m;i++) R(B[i]); SG[0]=0; for(i=1;i<=1000;i++) { memset(Mark,0,sizeof Mark); for(j=1;B[j]<=i&&j<=m;j++) { Mark[SG[i-B[j]]]=1; } for(j=0;;j++) if(!Mark[j]) { SG[i]=j; break; } } for(i=1;i<=n;i++) ans^=SG[A[i]]; if(ans) puts("YES"); else return 0*puts("NO"); for(i=1;i<=n;i++) { for(j=1;B[j]<=A[i]&&j<=m;j++) { if((ans^SG[A[i]]^SG[A[i]-B[j]])==0) { W(i); Wl(B[j]); return 0; } } } return 0; } /* input 4 7 6 9 3 2 1 2 output YES 1 1 input 10 97 73 45 72 9 13 55 84 61 27 4 2 5 7 9 output YES 6 7 */