1004 四子连棋
题目描述 Description
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● ○ ● ○ ● ○ ● ● ○ ● ○ ○ ● ○
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description
用最少的步数移动到目标棋局的步数。
样例输入 Sample Input
BWBO
WBWB
BWBW
WBWO
样例输出 Sample Output
5
#include <iostream> #include <cstring> using namespace std; #define MAX_N 4 #define MAX_Q 1000000 #define ADD(x) x=(x+1)%MAX_Q struct Node { int x[2],y[2]; char mat[MAX_N][MAX_N+1]; char Select;//Who play the chess int times; } queue[MAX_Q],tmp; int front,rear; char mat[MAX_N][MAX_N+1]; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; bool CanVisit(Node &node,int x,int y) { if(x<0 || x>=4 || y<0 || y>=4 || node.mat[y][x]!=node.Select) { return false; } return true; } bool OK(Node &node) { for(int i=0;i<4;i++) { if(node.mat[i][0]==node.mat[i][1] && node.mat[i][1]==node.mat[i][2] && node.mat[i][2]==node.mat[i][3]) return true; } if(node.mat[0][0]==node.mat[1][1] && node.mat[1][1]==node.mat[2][2] && node.mat[2][2]==node.mat[3][3]) return true; if(node.mat[0][3]==node.mat[1][2] && node.mat[1][2]==node.mat[2][1] && node.mat[2][1]==node.mat[3][0]) return true; for(int i=0;i<4;i++) { if(node.mat[0][i]==node.mat[1][i] && node.mat[1][i]==node.mat[2][i] && node.mat[2][i]==node.mat[3][i]) return true; } return false; } int main() { int ans=-1; int zcnt=0; int x[2],y[2]; for(int i=0;i<4;i++) { cin>>mat[i]; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) { if(mat[i][j]=='O') { x[zcnt]=j; y[zcnt]=i; zcnt++; } } front=rear=0; memcpy(tmp.mat,mat,sizeof(mat)); tmp.Select='B'; tmp.times=0; tmp.x[0]=x[0];tmp.y[0]=y[0]; tmp.x[1]=x[1];tmp.y[1]=y[1]; queue[rear]=tmp; ADD(rear); tmp.Select='W'; queue[rear]=tmp; ADD(rear); while(front!=rear) { tmp=queue[front]; ADD(front); if(tmp.Select=='W') tmp.Select='B'; else if(tmp.Select=='B') tmp.Select='W'; for(int i=0;i<4;i++) { int nx=tmp.x[0]+dx[i],ny=tmp.y[0]+dy[i]; if(CanVisit(tmp,nx,ny)) { Node tmp2=tmp; tmp2.mat[ny][nx]='O'; tmp2.x[0]=nx;tmp2.y[0]=ny; tmp2.mat[tmp.y[0]][tmp.x[0]]=tmp.Select; tmp2.times++; if(OK(tmp2)) { ans=tmp2.times; goto EndFind; } queue[rear]=tmp2; ADD(rear); } } for(int i=0;i<4;i++) { int nx=tmp.x[1]+dx[i],ny=tmp.y[1]+dy[i]; if(CanVisit(tmp,nx,ny)) { Node tmp2=tmp; tmp2.mat[ny][nx]='O'; tmp2.x[1]=nx;tmp2.y[1]=ny; tmp2.mat[tmp.y[1]][tmp.x[1]]=tmp.Select; tmp2.times++; if(OK(tmp2)) { ans=tmp2.times; goto EndFind; } queue[rear]=tmp2; ADD(rear); } } } EndFind: cout<<ans<<endl; return 0; }