题目链接:https://cn.vjudge.net/problem/HDU-5708
题意:if you are at (x,y), then you could move into (x+1,y), (x,y+1) or (x+k,y+k) at the next step.问先手是否胜出
题解:打表k不变,每个位置是必胜态还是必败态
打表发现,k为1时,偶数行列都为1,其他01循环,k不为1时,从(k+1,k+1)开始这一列和这一行,都为1,其他列,奇数01循环,偶数10循环
#include <bits/stdc++.h>
using namespace std;
int sg[110][110][110];
int getsg(int n,int m,int k)
{
if(n==1&&m==1)
{
return sg[n][m][k]=0;
}
if(sg[n][m][k]!=-1)
return sg[n][m][k];
//if(k==0) cout<<n<<" "<<m<<endl;
int flag=0;
if(n-1>=1)
{
if(getsg(n-1,m,k)==0)
{
flag=1;
}
}
if(m-1>=1)
{
if(getsg(n,m-1,k)==0)
{
flag=1;
}
}
if(k!=0)
{
if(n-k>=1&&m-k>=1)
{
if(getsg(n-k,m-k,k)==0)
{
flag=1;
}
}
}
//if(k==0) cout<<n<<" "<<m<<" "<<flag<<endl;
return sg[n][m][k]=flag;
}
int main(void)
{
memset(sg,-1,sizeof(sg));
int n,m,k;
for(k=1;k<=10;k++)
{
cout<<k<<"\n";
for(n=1;n<=10;n++)
{
for(m=1;m<=10;m++)
{
sg[n][m][k]=getsg(n,m,k);
printf(sg[n][m][k]?"1 ":"0 ");
}
cout<<"\n";
}
}
return 0;
}
代码:
#include<bits/stdc++.h>
using namespace std;
int q,k;
int main()
{
int T;
int x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&q,&k);
int flag;
while(q--)
{
scanf("%d%d",&x,&y);
if(y>x) swap(x,y);
if(k==1)
{
if(y&1)
{
if(x&1) flag=0;
else flag=1;
}
else flag=1;
}
else
{
if(y%(k+1)==0)
{
flag=1;
}
else if(y<k+1)
{
if(y&1)
{
if(x&1) flag=0;
else flag=1;
}
else
{
if(x&1) flag=1;
else flag=0;
}
}
else
{
x-=y/(k+1);
// cout<<x<<endl;
if(y&1)
{
if(x&1) flag=0;
else flag=1;
}
else
{
if(x&1) flag=1;
else flag=0;
}
}
}
printf(flag?"Alice\n":"Bob\n");
}
}
return 0;
}