洛谷 P2346 四子连棋

搜索专题

像这种棋盘问题,由于状态较多,且每个状态的储存量太大(复杂),一般用迭代加深较优

其实我是看了std做的。。。

source:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int mp[6][6],m1[5]={0,0,0,1,-1},m2[5]={0,1,-1,0,0},x[2],y[2];
bool flag=0;
bool check()
{
    for(int i=1;i<=4;i++)
    {
        if(mp[i][1]==mp[i][2]&&mp[i][1]==mp[i][3]&&mp[i][1]==mp[i][4])return 1;
        if(mp[1][i]==mp[2][i]&&mp[1][i]==mp[3][i]&&mp[1][i]==mp[4][i])return 1;
    }
    if(mp[1][1]==mp[2][2]&&mp[1][1]==mp[3][3]&&mp[1][1]==mp[4][4])return 1;
    if(mp[1][4]==mp[2][3]&&mp[1][4]==mp[3][2]&&mp[1][4]==mp[4][1])return 1;
    return 0;
}
void dfs(int p,int dep,int lun)//dfs(当前深度,限制深度,轮到黑还是白)
{
    if(flag==1) return;//若已经找到了,就返回
    if(check())//检查是否找到了
    {
        flag=1;//标记一下
        return;
    }
    if(p>dep) return;//大于限制深度就返回
    for(int i=1;i<=4;i++)//枚举移动方向
        for(int j=0;j<=1;j++)//枚举空格
        {
            int xx,yy;
            xx=x[j]+m1[i];yy=y[j]+m2[i];
            if(xx<1 || xx>4 || yy<1 || yy>4 || mp[xx][yy]!=lun/*检查是否下一个格子和轮到的一样*/) continue;
            swap(mp[xx][yy],mp[x[j]][y[j]]);
            x[j]=xx,y[j]=yy;
            int k=lun ^ 1;

            dfs(p+1,dep,k);

            x[j]-=m1[i],y[j]-=m2[i];
            swap(mp[xx][yy],mp[x[j]][y[j]]);
        }
}
int main(){

    //freopen("chess.in","r",stdin);
    //freopen("chess.out","w",stdout);
    int ans,cnt=0;
    char s[7];
    for(int i=1;i<=4;++i)
    {
        scanf("%s",s+1);
        for(int j=1;j<=4;++j)
            switch(s[j]){
                case 'B':mp[i][j]=1;break;
                case 'W':mp[i][j]=0;break;
                case 'O':
                    if(cnt==1)  x[0]=i,y[0]=j;
                    else x[1]=i,y[1]=j;
                    mp[i][j]=2,++cnt;
                    break;
            }
    }
    for(int k=1;!flag;k++)
    {
        dfs(1,k,0);
        dfs(1,k,1);
        if(flag) ans=k;
    }
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jiangbojun2017/article/details/81111250