四子连棋
题目描述 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
思路分析: bfs+hash判重,记录每次走过的棋局,进行每条直线与对角线的判断(类似于八皇后的判断),记录下一步该走黑棋还是白棋。
我是看的hzw神犇的blog才会的,程序基本上是理解了照搬过来的,不建议看。hzw神犇的题解-->http://hzwer.com/848.html
程序:
99%相同,题解是条不归路。
程序:
1 #include <iostream> 2 using namespace std; 3 struct data 4 { 5 int map[5][5]; 6 }dt[5000]; 7 int next[5000]={1,2}; 8 int step[5000]; 9 bool haxi[4000000]; 10 int x1[4]={0,0,1,-1}, 11 y1[4]={1,-1,0,0}; 12 int t=0,w=2,f=0; 13 int hash() 14 { 15 int k=1,s=0; 16 for (int i=1;i<=4;i++) 17 for (int j=1;j<=4;j++) 18 { 19 s+=dt[w].map[i][j]*k; 20 k*=3; 21 } 22 s%=3733799; 23 if (!haxi[s]) 24 { 25 haxi[s]=1; 26 return 1; 27 } 28 return 0; 29 } 30 bool pd4l(int a1,int b1,int c,int d) 31 { 32 if (a1!=b1||b1!=c||c!=d||a1!=d) return 0; 33 return 1; 34 } 35 bool fnis() 36 { 37 for (int i=1;i<=4;i++) 38 { 39 if (pd4l(dt[w].map[i][1],dt[w].map[i][2],dt[w].map[i][3],dt[w].map[i][4])) return 1; 40 if (pd4l(dt[w].map[1][i],dt[w].map[2][i],dt[w].map[3][i],dt[w].map[4][i])) return 1; 41 } 42 if (pd4l(dt[w].map[1][1],dt[w].map[2][2],dt[w].map[3][3],dt[w].map[4][4])) return 1; 43 if (pd4l(dt[w].map[1][4],dt[w].map[2][3],dt[w].map[3][2],dt[w].map[4][1])) return 1; 44 return 0; 45 } 46 void excg(int &a,int &b) 47 { int t; 48 t=a; 49 a=b; 50 b=t; 51 } 52 bool pd(int x,int y) 53 { int k; 54 k=next[t]; 55 if (x>4||x==0||y>4||y==0) return 0; 56 else if (dt[t].map[x][y]==k) return 1; 57 return 0; 58 } 59 void move(int x,int y) 60 { 61 int p,q; 62 for (int i=0;i<4;i++) 63 { 64 p=x1[i]+x; 65 q=y1[i]+y; 66 if (pd(p,q)) 67 { 68 for (int j=1;j<=4;j++) 69 for (int k=1;k<=4;k++) 70 dt[w].map[j][k]=dt[t].map[j][k]; 71 excg(dt[w].map[p][q],dt[w].map[x][y]); 72 step[w]=step[t]+1; 73 if (fnis()) {cout<<step[w]; f=1;return;} 74 if (hash()) 75 { 76 77 if (next[t]==1) next[w++]=2; 78 if (next[t]==2) next[w++]=1; 79 } 80 } 81 } 82 } 83 void search() 84 { 85 while (t<w) 86 { 87 for (int i=1;i<=4;i++) 88 for (int j=1;j<=4;j++) 89 { 90 if (dt[t].map[i][j]==0) 91 move(i,j); 92 if (f==1) return; 93 } 94 t++; 95 } 96 } 97 int main() 98 { 99 char x; 100 for (int i=1;i<=4;i++) 101 for (int j=1;j<=4;j++) 102 { 103 cin>>x; 104 if (x=='W') {dt[0].map[i][j]=dt[1].map[i][j]=1;} 105 if (x=='B') {dt[0].map[i][j]=dt[1].map[i][j]=2;} 106 // if (x=='O') {dt[0].map[i][j]=dt[1].map[i][j]=0;} 107 } 108 search(); 109 return 0; 110 }