一本通1666取石子游戏

取石子游戏

 

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
*/
View Code

 

posted @ 2019-03-18 20:34  yccdu  阅读(438)  评论(0编辑  收藏  举报