• (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 }
  • 相关阅读:
    java学习笔记4对象的初始化与回收
    java学习笔记2数据类型、数组
    java学习笔记3类与对象的基础
    java学习笔记5类的方法
    java学习笔记1开发环境平台总结
    BZOJ 4843
    SPOJ TTM
    BZOJ 4154
    POJ 3680
    半平面交模板 HDU 1469
  • 原文地址:https://www.cnblogs.com/quintessence/p/6052277.html
Copyright © 2020-2023  润新知