题意:给一个棋盘,两个人下棋,规则是可以放棋子,也可以拿棋子,在规定的步数内,谁先让棋盘出现重复谁就输。如果棋盘的两个状态通过旋转可以重合,则这两个状态重复。
思路:1.HASH保存每个状态,每走一步就检查是否重复并保存4个状态(4个方向)。
2.输出结果。
3.注意空棋盘的情况,还有一种情况是左转右转相同,所以要一个辅助标记initial。
右转90度:
(i,j)->(j,N-i-1)
左转90度:
(i,j)->(N-j-1,i)
转180度:
(i,j)->(N-i-1,N-j-1)
#include<stdio.h>
#include<string.h>
#define MAX 100003
int N,step,rear;
int state[MAX][55][55],map[55][55];
int head[MAX],next[MAX];
int hash(int n)
{
int i,j,v=0;
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
v=v*10+state[n][i][j];
v%=MAX;
}
}
return v%MAX;
}
int isExist(int n)
{
int h,u;
h=hash(n);
u=head[h];
if(!memcmp(state[u],state[n],sizeof(state[u])))return u;
while(u)
{
if(!memcmp(state[u],state[n],sizeof(state[u])))return u;
u=next[u];
}
next[n]=head[h];
head[h]=n;
return -1;
}
int Insert(int x,int y,int value)
{
int i,j,tag,initial;
int tmp[55][55];
map[x][y]=value;
memcpy(tmp,map,sizeof(map));
/*Save every state*/
memcpy(state[rear],tmp,sizeof(tmp));
if(isExist(rear)>=0)return 0;
else rear++;
initial=rear-1;
/*turn left*/
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
state[rear][i][j]=tmp[j][N-i-1];
}
}
tag=isExist(rear);
if(tag>=0&&tag<initial)return 0;
else rear++;
/*turn right*/
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
state[rear][i][j]=tmp[N-j-1][i];
}
}
tag=isExist(rear);
if(tag>=0&&tag<initial)return 0;
else rear++;
/*turn 180 degree*/
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
state[rear][i][j]=tmp[N-i-1][N-j-1];
}
}
tag=isExist(rear);
if(tag>=0&&tag<initial)return 0;
else rear++;
return 1;
}
int main()
{
int x,y,flag,i;
char c;
while(scanf("%d",&N)&&N)
{
step=1;flag=0;rear=1;
memset(head,0,sizeof(head));
memset(state[0],0,sizeof(state[0]));
memset(state[1],0,sizeof(state[1]));
memset(map,0,sizeof(map));
for(i=0;i<2*N;i++)
{
scanf("%d%d %c",&x,&y,&c);
if(c=='+')
{
if(Insert(x-1,y-1,1))step++;
else
{
printf("Player %d wins on move %d\n",step%2+1,step);
flag=1;
break;
}
}
else
{
if(Insert(x-1,y-1,0))step++;
else
{
printf("Player %d wins on move %d\n",step%2+1,step);
flag=1;
break;
}
}
}
if(flag)
{
for(;i<2*N-1;i++)
{
scanf("%d%d %c",&x,&y,&c);
}
}
else printf("Draw\n");
}
return 0;
}