四子连棋

题目描述

在一个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\n",ans);
80     return 0;
81 }

题目来源:洛谷

posted @ 2017-02-26 10:38  J_william  阅读(605)  评论(0编辑  收藏  举报