题目描述 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
分类标签 Tags 点此展开
#include<iostream> #include<cstdio> #include<queue> using namespace std; char a[6][6]; int b[6][6]; struct szlq { int a[6][6]; int b; int s; void print() { for(int i = 1;i <= 4;i ++,puts("")) for(int j = 1;j <= 4;j ++) printf("%d",a[i][j]); } }; queue<szlq> q; int ans,inf=21474836; bool judge(szlq a) { int e; for(int i=1;i<=4;i++) { e=a.a[i][1]; if(a.a[i][2]==e&&e==a.a[i][3]&&e==a.a[i][4]) return 1; e=a.a[1][i]; if(e==a.a[2][i]&&e==a.a[3][i]&&e==a.a[4][i]) return 1; } e=a.a[1][1]; if(e==a.a[2][2]&&e==a.a[3][3]&&e==a.a[4][4]) return 1; e=a.a[4][1]; if(e==a.a[3][2]&&e==a.a[2][3]&&e==a.a[1][4]) return 1; return 0; } int huan(int a) { return a==1?2:1; } void bfs(szlq a) { if(judge(a)==1) { ans=a.s; return; } szlq w; for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) { if(!a.a[i][j]) { if(a.a[i][j-1]==a.b) { w=a; w.b=huan(a.b); w.s+=1; swap(w.a[i][j],w.a[i][j-1]); q.push(w); } if(a.a[i][j+1]==a.b) { w=a; w.b=huan(a.b); w.s+=1; swap(w.a[i][j],w.a[i][j+1]); q.push(w); } if(a.a[i+1][j]==a.b) { w=a; w.b=huan(a.b); w.s+=1; swap(w.a[i][j],w.a[i+1][j]); q.push(w); } if(a.a[i-1][j]==a.b) { w=a; w.b=huan(a.b); w.s+=1; swap(w.a[i][j],w.a[i-1][j]); q.push(w); } } } } int main() { for(int i=1;i<=4;i++) scanf("%s",a[i]+1); for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) { if(a[i][j]=='B') b[i][j]=1; if(a[i][j]=='W') b[i][j]=2; } szlq ks,dq; for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) ks.a[i][j]=b[i][j]; ks.b=1;ks.s=0; q.push(ks); ks.b=2;ks.s=0; q.push(ks); ans=inf; while(ans==inf) { dq=q.front(); bfs(dq); q.pop(); } printf("%d",ans); }