Codevs 1004 四子连棋
1004 四子连棋
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold
题目描述 Description
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ |
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description
用最少的步数移动到目标棋局的步数。
样例输入 Sample Input
BWBO
WBWB
BWBW
WBWO
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
hi
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define Mod 9875321 7 #define maxn 1000005 8 long long read(){ 9 long long x=0,f=1;char ch=getchar(); 10 while(ch<'0'||ch>'9'){ 11 if(ch=='-')f=-1;ch=getchar(); 12 } 13 while(ch>='0'&&ch<='9'){ 14 x=x*10+ch-'0';ch=getchar(); 15 } 16 return x*f; 17 } 18 int head=0,tail=2,ans=-1; 19 int step[maxn],xx[4]={0,0,1,-1},yy[4]={1,-1,0,0}; 20 char q[maxn][5][5],a[5][5]; 21 bool last[maxn],mp[maxn*10]; 22 bool Valid(int x,int y,int t){ 23 //该函数用于判断与空白格子交换的合法性 24 if(x>4||y>4||x<1||y<1||a[x][y]=='O')return 0; 25 if(a[x][y]=='B'&&t==0)return 0; 26 if(a[x][y]=='W'&&t==1)return 0; 27 return 1; 28 } 29 bool equal(char a,char b,char c,char d){ 30 if(a!=b || b!=c || c!=d)return 0; 31 return 1; 32 } 33 int gethash(char a[5][5]){ 34 int t=0,key=0; 35 for(int i=1;i<=4;i++) 36 for(int j=1;j<=4;j++){ 37 if(a[i][j]=='O')t=0; 38 if(a[i][j]=='W')t=1; 39 if(a[i][j]=='B')t=2; 40 key=(key*3+t) % Mod; 41 } 42 return key; 43 } 44 bool check(char a[5][5]){ 45 for(int i=1;i<=4;i++){ 46 if(equal(a[i][1],a[i][2],a[i][3],a[i][4]))return 1; 47 if(equal(a[1][i],a[2][i],a[3][i],a[4][i]))return 1; 48 } 49 if(equal(a[1][1],a[2][2],a[3][3],a[4][4]))return 1; 50 if(equal(a[1][4],a[2][3],a[3][2],a[4][1]))return 1; 51 return 0; 52 } 53 void Move(int x,int y){ 54 for(int k=0;k<4;k++){ 55 int tx=x+xx[k],ty=y+yy[k]; 56 if(!Valid(tx,ty,last[head]))continue; 57 58 for(int i=1;i<=4;i++) 59 for(int j=1;j<=4;j++) 60 a[i][j]=q[head][i][j]; 61 62 swap(a[x][y],a[tx][ty]); 63 if(mp[gethash(a)])continue; 64 mp[gethash(a)]=1; 65 tail++; 66 for(int i=1;i<=4;i++) 67 for(int j=1;j<=4;j++) 68 q[tail][i][j]=a[i][j]; 69 70 step[tail]=step[head]+1; 71 last[tail]=last[head]^1; 72 if(check(a))ans=step[tail]; 73 } 74 } 75 void BFS(){ 76 while(head != tail){ 77 for(int i=1;i<=4;i++) 78 for(int j=1;j<=4;j++) 79 if(q[head][i][j]=='O') 80 Move(i,j); 81 if(ans != -1) return; 82 head++; 83 } 84 } 85 int main() 86 { 87 for(int i=1;i<=4;i++) 88 scanf("%s",a[i]+1); 89 for(int i=1;i<=4;i++) 90 for(int j=1;j<=4;j++) 91 q[0][i][j]=q[1][i][j]=a[i][j]; 92 93 last[0]=0;last[1]=1; 94 BFS(); 95 printf("%d\n",ans); 96 return 0; 97 }