Gym - 101667B Connect3 (dfs模拟)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a54665sdgf/article/details/82153986

题目链接

题意:两个人轮流从棋盘上分别放置黑白两色的棋子,每次只能从最低位放置。给你规定第一枚黑棋和最后一枚白棋放置的位置,让你求出总共有多少种局面,使得该局面白棋胜利。(横竖斜至少有一个方向存在连续的三枚同色棋子即可胜利)

思路:一看到从低位到高位,首先想到dp,再一想,要判断是否胜利需要用到下面棋子的状态,不可取,放弃。

然后就是dfs了,没什么技巧,就是纯粹的模拟放置棋子的过程。注意当某一列棋子放满之后就不能继续放了,而且若当前局面已有一方胜利或者有棋子放置在终点的时候要return。若放置在终点的棋子为白棋并且白棋此时能赢,则++ans。

另外要用set来保存当前局面的状态,以防重复。

比赛的时候脑子崩了,狂出bug...

#define FRER() freopen("i.txt","r",stdin)
#define FREW() freopen("o.txt","w",stdout)
#define dbg puts("--------------------");
#include<bits/stdc++.h>
#include<unordered_set>

typedef long long ll;
using namespace std;
const int N=4+2;
int a[N][N];
int cnt[N];
int X0,X1,Y1;
int ans;
ll state()
{
    ll key=0;
    for(int i=3; i>=0; --i)
        for(int j=0; j<=3; ++j)
            key=key*3+a[j][i];
    return key;
}

unordered_set<ll> vis;

bool win(int p)
{
    for(int y=0; y<=3; ++y)
        for(int x=0; x<=1; ++x)
            if(a[x][y]==p&&a[x+1][y]==p&&a[x+2][y]==p)return true;
    for(int x=0; x<=3; ++x)
        for(int y=0; y<=1; ++y)
            if(a[x][y]==p&&a[x][y+1]==p&&a[x][y+2]==p)return true;
    if(a[0][2]==p&&a[1][1]==p&&a[2][0]==p)return true;
    if(a[0][3]==p&&a[1][2]==p&&a[2][1]==p)return true;
    if(a[1][2]==p&&a[2][1]==p&&a[3][0]==p)return true;
    if(a[1][3]==p&&a[2][2]==p&&a[3][1]==p)return true;
    if(a[0][1]==p&&a[1][2]==p&&a[2][3]==p)return true;
    if(a[0][0]==p&&a[1][1]==p&&a[2][2]==p)return true;
    if(a[1][1]==p&&a[2][2]==p&&a[3][3]==p)return true;
    if(a[1][0]==p&&a[2][1]==p&&a[3][2]==p)return true;
    return false;
}

void dfs(int p)
{
    ll 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;
        return;
    }
    for(int x=0; x<4; ++x)
    {
        if(cnt[x]==4)continue;
        int y=cnt[x];
        a[x][cnt[x]++]=p;
        dfs(p^3);
        a[x][y]=0;
        cnt[x]--;
    }
}

int main()
{
    //freopen("i.txt","r",stdin);
    //freopen("o.txt","w",stdout);
    scanf("%d%d%d",&X0,&Y1,&X1);
    X0--,Y1--,X1--;
    a[X0][cnt[X0]++]=1;
    dfs(2);
    printf("%d\n",ans);
    return 0;
}
//

猜你喜欢

转载自blog.csdn.net/a54665sdgf/article/details/82153986