Gym - 101667B—Connect3 (dfs)

版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/82491437

题目链接:https://odzkskevi.qnssl.com/6fd8c99567698f4bad5a228cc982bad7?v=1535352582

题意:

给出先手黑棋的位置(1,x)和最后一子白棋的位置(x1,y1),三子相连即胜利,问最后白棋获胜的可能状态有多少种,每次只能下在某一列的最低位置处。

思路:

dfs模拟下棋,详见代码:

#include<bits/stdc++.h>
#include<unordered_set>

using namespace std;
const int N=4+2;
int a[N][N],cnt[N];//cnt用来记录每列已经下了多少棋子
int X0,X1,Y1,ans;
unordered_set<unsigned int> vis;

unsigned int state()
{
    unsigned int sum=0;
    for(int i=0; i<=3; ++i)
        for(int j=0; j<=3; ++j)
            sum=sum<<2|a[j][i];//确保状态唯一性
     return sum;
}

bool win(int p)
{
    for(int x=0; x<=3; ++x)
        for(int y=0; y<=3; ++y)
        {
            if(x+2<=3&&a[x][y]==p&&a[x+1][y]==p&&a[x+2][y]==p)return true;//竖
            if(y+2<=3&&a[x][y]==p&&a[x][y+1]==p&&a[x][y+2]==p)return true;//横
            if(x+2<=3&&y+2<=3&&a[x][y]==p&&a[x+1][y+1]==p&&a[x+2][y+2]==p)return true;//右上
            if(x-2>=0&&y+2<=3&&a[x][y]==p&&a[x-1][y+1]==p&&a[x-2][y+2]==p)return true;//左上
        }
    return false;
}

void dfs(int p)
{
    unsigned int k=state();
    if(vis.count(k))return;
    vis.insert(k);
    if(win(1)||win(2)||a[X1][Y1])
    {
        if(win(2)&&a[X1][Y1]==2)
            ++ans;//以白棋在x1,y1处结尾且白棋连续
        return;
    }
    for(int x=0; x<=3; ++x)//四列分别放棋
    {
        if(cnt[x]==4)continue;
        a[x][cnt[x]++]=p;
        dfs(p^3);//p=2时p^3为1,反之为2(按位异或,不同为1,相同为0)
        a[x][--cnt[x]]=0;//回溯
    }
}

int main()
{
    scanf("%d%d%d",&X0,&Y1,&X1);
    X0--,Y1--,X1--;//下标从0开始
    a[X0][cnt[X0]++]=1;//1代表黑,2代表白
    dfs(2);
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Healer66/article/details/82491437