黑白棋(博弈论)

原题链接

1045: 黑白棋
时间限制: 1 Sec 内存限制: 128 MB
提交: 79 解决: 36
[提交][状态][讨论版]
题目描述

定义一种新的黑白棋:

  1. 棋盘大小为5*5的格子;

  2. 有些格子不能放棋子;

  3. 同一个格子最多放一个棋子;

  4. 先手执白棋,后手执黑棋;

  5. 先手第一次可以把棋放在任意可以放的位置上;

  6. 接下来两人轮流放棋子,这个棋子必须与上一个人放的棋子相邻

请问:两人都是最优策略,是先手赢,还是先手输?

这里写图片描述
这里写图片描述
输入
2
11111
11111
11111
11111
00000
11111
11111
11111
11111
10000
输出
win
lose

主要就是利用DFS实现递归查询当前步是不是一定赢,而当前步赢是由后一步一定输来决定的,如果后一步存在一定赢的情况,那么当前状态就一定输了,然后一步步递归得到正确的答案


#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

const int MOD = int(1e9) + 7;
const int INF = 0x3f3f3f3f;
const int fx[] = {-1, 1, 0, 0};
const int fy[] = {0, 0, -1, 1};
const int maxn=7;
int a[maxn][maxn];
bool can(int x,int y){
        if(x<0||x>=5||y<0||y>=5||a[x][y]!=0) return false;
        else return true;
}
bool dfs(int x,int y){
        a[x][y]=1;
        for(int i=0;i<4;i++){
                int newx=x+fx[i];
                int newy=y+fy[i];
                if(can(newx,newy)){
                        if(dfs(newx,newy)){
                                a[x][y]=0;
                                return false;//有一个方向当前手的后手赢那么他肯定输
                        }
                }
        }
        a[x][y]=0;
        return true;//如果当前没有可以走的地方或者是可以走的方向他都是赢的话
}
int main(){
        int T;
        cin >> T;
        while(T--){
                for(int i=0;i<5;i++){
                        for(int j=0;j<5;j++){
                                scanf("%1d",&a[i][j]);//这里就实现了只读一位整数
                        }
                }
                bool flag=false;
                for(int i=0;i<5;i++){
                        for(int j=0;j<5;j++){
                                if(can(i,j)){
                                        if(dfs(i,j))
                                                flag=true;//先手只要有一个地方放下去必赢那么肯定就赢了
                                }
                        }
                }
                if(flag) printf("win\n");
                else printf("lose\n");
        }
        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

门豪杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值