(DFS)codevs1004-四子连棋

题目地址

方法是建立dfs,并在其中加入pre变量,记录之前移动的是W还是B。外面套for循环,从1步开始逐次递增,直到在i步时可以走完(dfs返回1),break退出循环,即为最短步。

本题的关键主要是可能有走过来又走回去的无用情况。对于这道题,即使在最坏的情况,也基本上可以保证在15步以内(并未证明)达到目标状态,所以可以在dfs中加入step进行限制,step等于外面for循环中的循环变量时就结束。这样就有效避免了死循环的出现,对于处理这道题的情况比较方便。

注:以下代码未考虑起始时就满足条件的情况。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 char a[10][10];
 6 int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}},ans,ox1=-1,ox2,oy1,oy2;//dir数组储存方向,oxoy记录两个空位
 7 bool check()//检验此时棋盘是否满足条件
 8 {
 9         if(a[0][0]==a[1][1]&&a[1][1]==a[2][2]&&a[2][2]==a[3][3])
10             return true;
11         if(a[3][0]==a[2][1]&&a[3][0]==a[1][2]&&a[3][0]==a[0][3])
12             return 1;
13         for(int i=0;i<4;i++)
14         {
15             if(a[i][0]==a[i][1]&&a[i][1]==a[i][2]&&a[i][2]==a[i][3])
16                 return 1;
17             if(a[0][i]==a[1][i]&&a[1][i]==a[2][i]&&a[2][i]==a[3][i])
18                 return 1;
19         }
20         return 0;
21 }
22 bool val(int x,int y,char p)//检验位置是否合法
23 {
24     return x>=0&&x<4&&y>=0&&y<4&&a[x][y]!=p;
25 }
26 bool dfs(int x1,int y1,int x2,int y2,char pre,int step)
27 {
28     if(step==ans)
29     {
30         if(check()) return 1;
31         else return false;
32     }
33     for(int i=0;i<4;i++)
34     {
35         int xn,yn,xm,ym;
36         xn=x1+dir[i][0];
37         xm=x2+dir[i][0];
38         yn=y1+dir[i][1];
39         ym=y2+dir[i][1];
40         if(val(xn,yn,pre))
41         {
42             swap(a[x1][y1],a[xn][yn]);
43             if(dfs(xn,yn,x2,y2,(pre=='B'?'W':'B'),step+1))return 1;//灵活运用三元运算符
44             swap(a[x1][y1],a[xn][yn]);
45         }
46         if(val(xm,ym,pre))
47         {
48             swap(a[x2][y2],a[xm][ym]);
49             if(dfs(x1,y1,xm,ym,(pre=='B'?'W':'B'),step+1))return 1;
50             swap(a[x2][y2],a[xm][ym]);
51         }
52     }
53     return 0;
54 }
55 int main()
56 {
57     int i,x=0,j;
58     for(i=0;i<4;i++)
59         scanf("%s",a[i]);
60     for(i=0;i<4;i++)
61     {
62         for(j=0;j<4;j++)
63         {
64             if(a[i][j]=='O')
65             {
66                 if(ox1==-1)
67                 {
68                     ox1=i;oy1=j;
69                 }
70                 else
71                     {ox2=i;oy2=j;}
72             }
73         }
74     }
75     for(ans=1;ans<100000;ans++)//从第一步开始逐次进行
76     {
77         if(dfs(ox1,oy1,ox2,oy2,'W',0))
78             break;
79         if(dfs(ox1,oy1,ox2,oy2,'B',0))
80             break;
81     }
82     printf("%d
",ans);
83     return 0;
84 }
原文地址:https://www.cnblogs.com/quintessence/p/6052277.html