zoukankan      html  css  js  c++  java
  • codevs1044四子连棋(Dfs)

    /*
    数据范围太小 暴力暴力 Dfs直接 
    终止条件嘛 就是4中目标棋局 挨着枚举一遍就好了 
    搜索的起点一定是空格 当然 空格周围有黑有白 黑先走或者白先走答案可能不一样
    所以 维护一个b 表示这一步走那种颜色  b=1先走白棋 b=2先走黑棋
     
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int xx[5]={0,0,0,1,-1};//枚举四个方向 
    int yy[5]={0,1,-1,0,0};
    int g[5][5],minn=1000;//最小步数 
    char s;
    void Dfs(int x,int y,int num,int b)//b表示 先走那种颜色 
    {
        int m=100000,i,j,k;
        if(num>=minn) return; //剪枝 如果已经比目前的最优解大了 就不用再Dfs了 
        for(i=1;i<=4;i++)//4种目标棋局一一列举 如果有符合的 更新m的值 
          {
              if(g[i][1]==g[i][2]&&g[i][2]==g[i][3]&&g[i][3]==g[i][4]&&(g[i][4]==1||g[i][4]==2))m=num;
              if(g[1][i]==g[2][i]&&g[2][i]==g[3][i]&&g[3][i]==g[4][i]&&(g[4][i]==1||g[4][i]==2))m=num;
          }
        if(g[1][1]==g[2][2]&&g[2][2]==g[3][3]&&g[3][3]==g[4][4]&&(g[4][4]==1||g[4][4]==2))m=num;
        if(g[4][1]==g[3][2]&&g[3][2]==g[2][3]&&g[2][3]==g[1][4]&&(g[1][4]==1||g[1][4]==2))m=num;
        if(m<minn)//用m更新minn 
          {
              minn=m;
              return;//不用往后Dfs了 因为后面不如现在优 
          }
        for(i=1;i<=4;i++)
          {
              int ox=x+xx[i];
              int oy=y+yy[i];
              if(ox>0&&ox<=4&&oy>0&&oy<=4&&g[ox][oy]==b)
                {
                    g[x][y]=g[ox][oy];
                    g[ox][oy]=0;//走完之后g[ox][oy]变空  g[x][y]变g[ox][oy]
                if(b==1)b=2;//黑白交替走 上次走黑 下次走白 
                    else b=1;
                    for(j=1;j<=4;j++)//因为空格又不止一个 所以 找空格0.0 
                      for(k=1;k<=4;k++)
                        if(!g[j][k])//
                          Dfs(j,k,num+1,b);
                    g[ox][oy]=g[x][y];//回溯 
                    g[x][y]=0;
                    if(b==1)b=2;
                    else b=1;
              }
          }
    }
    int main()
    {
        int i,j;
        for(i=1;i<=4;i++)
          for(j=1;j<=4;j++)
            {
              cin>>s;
              if(s=='W')g[i][j]=1;//白棋 
              if(s=='B')g[i][j]=2;//黑棋 
            }
        for(i=1;i<=4;i++)
          for(j=1;j<=4;j++)
            if(!g[i][j])//空格 
              {
                  Dfs(i,j,0,1);//先走白棋 
                  Dfs(i,j,0,2);//先走黑棋 
              }
        cout<<minn<<endl;
        return 0;
    }
  • 相关阅读:
    数组的学习——有序数组中插入及删除数值的问题分析
    关于控制台输入年月,显示该月日历的问题分析
    关于控制台的输入,分支结构及循环的用法的一些总结
    坚持学习,坚持写博客,记录学习的点点滴滴,先从学习JAVA开始!
    Immutable Object模式
    Windows GIT SSH 免密教程
    腾讯云服务器购买
    Centos7系统中安装JDK、Tomcat、Mysql
    SonarQube使用教程
    UEditor使用说明
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5424129.html
Copyright © 2011-2022 走看看