Circle vs Triangle(DFS+博弈)

本文介绍了一个基于棋盘的游戏——圆圈对三角形,通过分析游戏规则及应用博弈论思想,探讨了如何判断先手玩家是否拥有必胜策略,并提供了一段实现该策略判断的C++代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

B - Circle vs Triangle

Time Limit:  2000/1000MS (Java/Others)     Memory Limit:  128000/64000KB (Java/Others)
Problem Description

Alice and Bob invent a new game called "circle vs triangle". At first there are a rectangle map, which consists of n*m unit-squares. Then lady first. Alice can choose any unit square and write a circle in it. And then Bob choose a unit square which next to the one that Alice just choose, and write a triangle in it. Turning to Alice again. Each player should choose a unit square which next to the one that another one chooses, and write a shape standing for him or her.

However, Alice and Bob find such silly game is so boring. Then they let some square in the map become barriers, which means these square can't be written anything on it.

So, give you a map, please tell me who can win or it can lead to a draw, if both Alice and Bob make a optimal choice.

Input
Multiple case, and each case to begin with two integers: n,m(1<=n,m<=5).
Then an n*m map is shown. Please read the sample to get more informations.
Output
If the map can lead to a draw, please output "Draw".
Otherwise, please output the name of player who can win if both make optimal choice.
Sample Input
3 3
***
***
...
3 3
***
**.
...
Sample Output
Alice
Bob
Hint
For the first case, Alice can write a circle at the left lower corner, then Bob has to write a triangle beside it. After Alice write a circle at the right lower corner, Bob has no way to write. So Alice win.
For the second case, Bob will win in the end wherever Alice choose firstly.



题目大意:在一个棋盘上,Alice和Bob两人轮流放棋子,Alice先手,问Alice是否必胜


分析:首先介绍一下博弈的思想。

对于1VS1的棋类游戏而言,如果这一步我有必胜策略,那我就可以必胜;如果无论我这一步怎么操作,对方都有必胜策略,那么我就必败。注意前一句的条件是“存在”,后一句是“任意”。这两句话构成了博弈论的基石。

然后,就可以DFS搜是否存在必胜策略即可。


代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct Node {
    int x, y;
}node[40];
int n, m;
char mp[10][10];
int vis[10][10];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

bool dfs(int x, int y) {
    int flag = 0;
    for(int i = 0; i < 4; i++) {
        int tx = x+dx[i];
        int ty = y+dy[i];
        if(tx < 0 || tx >= n || ty < 0 || ty >= m || mp[tx][ty] == '*' || vis[tx][ty]) continue;
        vis[tx][ty] = 1;
        if(dfs(tx, ty)) {
            flag = 1;
            break;
        }
        vis[tx][ty] = 0;
    }
    if(flag) return 0;
    else return 1;
}


int main() {
    while(~scanf("%d%d", &n, &m)) {
        int cnt = 0;
        for(int i = 0; i < n; i++) {
            scanf("%s", mp[i]);
            for(int j = 0; j < m; j++) {
                if(mp[i][j] == '.') {
                    node[cnt].x  = i;
                    node[cnt++].y = j;
                }
            }
        }
        memset(vis, 0, sizeof(vis));
        int flag = 0;
        for(int i = 0; i < cnt; i++) {
            int tx = node[i].x, ty = node[i].y;
            vis[tx][ty] = 1;
            if(dfs(tx, ty)) {
                flag = 1;
                break;
            }
            vis[tx][ty] = 0;
        }
        if(flag) printf("Alice\n");
        else printf("Bob\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值