四子连棋
【题目描述】
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ |
【输入描述】
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
【输出描述】
用最少的步数移动到目标棋局的步数。
【样例输入】
BWBO
WBWB
BWBW
WBWO
【样例输出】
5
DFS:
源代码: #include<iostream> using namespace std; #define INF 100000000 int ans=10,i[5][5],x[4]={-1,0,0,1},y[4]={0,-1,1,0}; //偷懒的好办法。 void Search(int t1,int t2,int num,int s) { if (num>=ans) //回去吧。 return; int t=INF; for (int a=1;a<=4;a++) //查询此情况是否合法。 { if (i[a][1]==i[a][2]&&i[a][2]==i[a][3]&&i[a][3]==i[a][4]) t=num; if (i[1][a]==i[2][a]&&i[2][a]==i[3][a]&&i[3][a]==i[4][a]) t=num; } if (i[1][1]==i[2][2]&&i[2][2]==i[3][3]&&i[3][3]==i[4][4]) t=num; if (i[1][4]==i[2][3]&&i[2][3]==i[3][2]&&i[3][2]==i[4][1]) t=num; if (t<ans) //回去吧。 { ans=t; return; } for (int a=0;a<4;a++) if (t1+x[a]<5&&t1+x[a]>0&&t2+y[a]<5&&t2+y[a]>0&&i[t1+x[a]][t2+y[a]]==s) //符合条件。 { i[t1][t2]=s; i[t1+x[a]][t2+y[a]]=0; s=s==1?2:1; for (int b=1;b<=4;b++) for (int c=1;c<=4;c++) if (!i[b][c]) Search(b,c,num+1,s); s=s==1?2:1; //回溯。 i[t1+x[a]][t2+y[a]]=s; i[t1][t2]=0; } } int main() //DFS。 { for (int a=1;a<=4;a++) for (int b=1;b<=4;b++) { char t; cin>>t; //论字符串读入的坑爹性。 if (t=='W') i[a][b]=1; if (t=='B') i[a][b]=2; if (t=='O') i[a][b]=0; } for (int a=1;a<=4;a++) for (int b=1;b<=4;b++) if (!i[a][b]) //黑白交替进行。 { Search(a,b,0,1); Search(a,b,0,2); } cout<<ans; return 0; }
BFS: