[BZOJ1874] [BeiJing 2009 WinterCamp] 공기 뽑기 게임(게임 SG 함수)

4357 단어 wc게임bzoj

제목 설명


전송문

문제풀이


SG 함수로 NP 국면 구하기;필승태라면 가장 작은 것을 일일이 열거하면 된다.

코드

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

const int max_n=15;
const int max_m=15;
const int max_sg=1005;

int n,m,k;
int a[max_n],rule[max_m];
int sg[max_sg];
bool ext[max_sg];

inline void get_sg(){
    memset(sg,0,sizeof(sg));
    for (int i=1;i<=1000;++i){
        memset(ext,0,sizeof(ext));
        for (int j=1;j<=m;++j){
            if (i-rule[j]<0) break;
            ext[sg[i-rule[j]]]=true;
        }
        for (int j=0;;j++)
          if (!ext[j]){
            sg[i]=j;
            break;
          }
    }
}

int main(){
    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",&rule[i]);
    sort(rule+1,rule+m+1);

    get_sg();

    k=0;
    for (int i=1;i<=n;++i)
      k^=sg[a[i]];
    if (!k) printf("NO
"
); else printf("YES
"
); for (int i=1;i<=n;++i){ k^=sg[a[i]]; for (int j=1;j<=m;++j){ if (a[i]-rule[j]<0) break; if (!(k^sg[a[i]-rule[j]])){ printf("%d %d
"
,i,rule[j]); return 0; } } k^=sg[a[i]]; } }

좋은 웹페이지 즐겨찾기