一道基础博弈sg题,据说要用递归调用sg函数,我用了比较笨的的方法,毕竟这是我第一道博弈 sg题,先练一下基础哈:
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int move[101];
int sg[10001];
int vis[10001];
int main()
{
//freopen("out","w",stdout);
int n_move;
while(scanf("%d",&n_move),n_move)
{
int i,j;
memset(sg,-1,sizeof(sg));
for(i=0;i<n_move;i++)
scanf("%d",&move[i]);
sg[0]=0;
sort(move,move+n_move);
for(i=1;i<10001;i++)
{
memset(vis,-1,sizeof(vis));
int j;
for(j=0;j<n_move&&move[j]<=i;j++)
vis[sg[i-move[j]]]=0;
for(j=0;;j++)
if(vis[j]==-1)
{
sg[i]=j;
break;
}
}
int n;
scanf("%d",&n);
for(i=0;i<n;i++)
{
int nn,m;
scanf("%d",&nn);
for(j=0;j<nn;j++)
{
int a;
scanf("%d",&a);
if(j==0)
m=sg[a];
else
m^=sg[a];
}
if(m==0)
printf("L");
else
printf("W");
}
printf("\n");
}
}
不过上面的代码由于效率太低通不过,下面是改进版本(好吧我承认我是看到题解才想到用递归)
#include<iostream>
#include<stdio.h>
using namespace std;
int move[101];
int sg[10001];
int n_move;
int getsg(int a)
{
if(sg[a]!=-1)
return sg[a];
if(a-move[0]<0)
return sg[a]=0;
int hand[100],i;
memset(hand,0,sizeof(hand));
for(i=0;i<n_move&&move[i]<=a;i++)
hand[getsg(a-move[i])]=1;
for(i=0;;i++)
if(hand[i]==0)
return sg[a]=i;}
int main()
{
while(scanf("%d",&n_move),n_move)
{
int i,j;
memset(sg,-1,sizeof(sg));
sg[0]=0; for(i=0;i<n_move;i++)
scanf("%d",&move[i]);
sort(move,move+n_move);
int n_case;
scanf("%d",&n_case);
for(i=0;i<n_case;i++)
{ int n,m; scanf("%d",&n);
for(j=0;j<n;j++)
{
int a; scanf("%d",&a);
if(j==0) m=getsg(a);
else m^=getsg(a);
}
//cout<<sg[5]<<" "<<sg[12]<<endl;
if(m==0)
printf("L");
else printf("W");
}
printf("\n");
}
}