bzoj4600 [Sdoi2016] coin game sg function + conclusion

sg[maxQ][The number of times of two][The number of times of three]=The previous ones are all positive wins and losses

C is different and independent of each other

First, the order is not important, because he has an imitation relationship.

For example, 9, 3 is 0, the winning strategy is to choose 9 to turn 9, 3

  Because it is an exclusive OR, the winning strategy can be understood as choosing 9 to turn 9, so that the position of 3 needs to be turned twice, which is equivalent to turning 0 times

It can be understood that the position of 3 is already 0 (the actual operation is equivalent to imitating)

Therefore, if there is a winning strategy, it must be divided into several combinations of the sg value of each point. Pick a 0 point to change the previous 0 point to 1

It can be understood in an independent point angle to keep the previous 0 point, and use the sg of the previous 0 point to XOR equal to 0,

Because if the first hand is 0, the second hand must be 1, the first hand is 1, and the second hand must be 0, which is equivalent to not being able to turn.

It can also be understood by the nature of XOR. .

code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int sg[23][55][55],n,T,i,j,Q,ans,o,er[30005],san[30005];
int SG(int Q,int a,int b)
{
	if(sg[Q][a][b]!=-1)return sg[Q][a][b];
int i,j,q,p;
bool v[101];
memset(v,0,sizeof(v));
for(p=1;p<=a;p++)
{int lin=0;
for(q=1;q<=Q;q++)
{
if(p*q>a)break;	
	lin^=SG(Q,a-p*q,b);
	v[lin]=1;
}
}
for(p=1;p<=b;p++)	
{int lin=0;
for(q=1;q<=Q;q++)
{
if(p*q>b)break;	
	lin^=SG(Q,a,b-p*q);
	v[lin]=1;
}
}
	for(i=0;i<=100;i++)
	{
		if(v[i]==0)
		{sg[Q][a][b]=i;break;}
	}
	return sg[Q][a][b];
}
int main()
{
	scanf("%d",&T);
	memset(sg,-1,sizeof(sg));
	for(Q=1;Q<=20;Q++)
	for(i=0;i<=15;i++)
	for(j=0;j<=15;j++)
	{
		SG(Q,i,j);
	}
	int linn=0;
	for(i=1;i<=30000;i++)
	{
		o=i;
			int o2=0;
			int o3=0;
			while(o%2==0)
			o/=2,o2++;
			while(o%3==0)
			o/=3,o3++;
			er[i]=o2;san[i]=o3;
		linn=max(linn,max(o2,o3));
	}
	while(T--)
	{ans=0;
		scanf("%d%d",&n,&Q);
		for(i=1;i<=n;i++)
		{
			scanf("%d",&o);
			if(o==1)continue;
			ans^=sg[Q][er[i]][san[i]];
		}
		if(ans==0)printf("lose\n");
		else printf("win\n");
	}
 } 

  


Guess you like

Origin blog.csdn.net/haobang866/article/details/79465905