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;
}

 

posted @ 2016-04-23 10:50  一入OI深似海  阅读(244)  评论(0编辑  收藏  举报