题目描述
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● ○ ●
○ ● ○ ●
● ○ ● ○
○ ● ○
输入输出格式
输入格式:
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出格式:
用最少的步数移动到目标棋局的步数。
输入输出样例
输入样例#1:
BWBO WBWB BWBW WBWO
输出样例#1:
5
思路:深度优先搜索+特殊的状态储存。
我是用二的幂储存的状态。
因为是很早以前的代码了,我有点看不懂。
另外黑白棋子谁先手是有影响的。
有关黑棋的变量应该都一个字母‘b’,同样有关白棋的有一个‘w’,行是‘h’,列是‘l’。
代码实现:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 int ww,bb,ans=300; 6 int w[7][2],b[7][2],h[4]; 7 int hb[]={-1,0,1,0},lb[]={0,1,0,-1};//行变和列变。 8 int ew[]={2,4,8,16},eb[]={32,64,128,256}; 9 char ch; 10 void dfs(int step,int x){ 11 if(step>ans) return; 12 if(step>0){ 13 for(int i=0;i<4;i++) 14 if(h[i]==30||h[i]==480){ans=step;return;} 15 for(int i=0;i<4;i++){ 16 if(h[0]&ew[i]&&h[1]&ew[i]&&h[2]&ew[i]&&h[3]&ew[i]){ans=step;return;} 17 if(h[0]&eb[i]&&h[1]&eb[i]&&h[2]&eb[i]&&h[3]&eb[i]){ans=step;return;} 18 } 19 for(int i=0;i<5;i++){ 20 if(i==4){ans=step;return;} 21 if(!(h[i]&ew[i])) break; 22 } 23 for(int i=0;i<5;i++){ 24 if(i==4){ans=step;return;} 25 if(!(h[i]&ew[3-i])) break; 26 } 27 for(int i=0;i<5;i++){ 28 if(i==4){ans=step;return;} 29 if(!(h[i]&eb[i])) break; 30 } 31 for(int i=0;i<5;i++){ 32 if(i==4){ans=step;return;} 33 if(!(h[i]&eb[3-i])) break;//注意逻辑运算与或非的优先度。 34 } 35 } 36 if(x!=1){//移白棋 。 37 for(int i=0;i<7;i++) 38 for(int j=0;j<4;j++){ 39 int ah=w[i][0],bl=w[i][1]; 40 int nh=ah+hb[j],nl=bl+lb[j]; 41 if((!(h[nh]&ew[nl]))&&(!(h[nh]&eb[nl]))&&nh>=0&&nh<4&&nl>=0&&nl<4){ 42 h[nh]+=ew[nl];h[ah]-=ew[bl]; 43 w[i][0]=nh;w[i][1]=nl; 44 dfs(step+1,1); 45 h[nh]-=ew[nl];h[ah]+=ew[bl]; 46 w[i][0]=ah;w[i][1]=bl; 47 } 48 } 49 } 50 if(x!=0){//移黑棋。 51 for(int i=0;i<7;i++) 52 for(int j=0;j<4;j++){ 53 int ah=b[i][0],bl=b[i][1]; 54 int nh=ah+hb[j],nl=bl+lb[j]; 55 if((!(h[nh]&ew[nl]))&&(!(h[nh]&eb[nl]))&&nh>=0&&nh<4&&nl>=0&&nl<4){ 56 h[nh]+=eb[nl];h[ah]-=eb[bl]; 57 b[i][0]=nh;b[i][1]=nl; 58 dfs(step+1,0); 59 h[nh]-=eb[nl];h[ah]+=eb[bl]; 60 b[i][0]=ah;b[i][1]=bl; 61 } 62 } 63 } 64 } 65 int main(){ 66 for(int i=0;i<4;i++) 67 for(int j=0;j<4;j++){ 68 cin>>ch; 69 if(ch=='W'){ 70 h[i]+=ew[j]; 71 w[ww][0]=i;w[ww++][1]=j; 72 } 73 if(ch=='B'){ 74 h[i]+=eb[j]; 75 b[bb][0]=i;b[bb++][1]=j; 76 } 77 } 78 dfs(0,2);//这里是2,所以黑棋先手白棋先手各一遍。 79 printf("%d ",ans); 80 return 0; 81 }
题目来源:洛谷