ACDREAM 05B Circle vs Triangle(DFS专场)

在这篇博客中,我们探讨了一款新颖的游戏——‘圈与三角’。游戏规则简单,但充满策略。Alice 和 Bob 在有障碍的地图上轮流放置形状,目标是阻止对手放置。通过深度优先搜索(DFS)算法,我们揭示了如何判断最终的胜利者,展现了博弈论的魅力。

ACDREAM 05B Circle vs Triangle

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.

题目大意:两个人在有障碍的棋盘上下棋,游戏规则释放棋子,谁先放不了,谁就输。并且下一个人放棋子的位置必须是上一个人放棋子位置的周围(上下左右,第一个下棋的人可以任意放在无障碍的位置上)。两个人都会选择最优下法。问最后的获胜者是谁。
解题思路:DFS + 博弈。遍历起始位置,进行DFS。寻找必败态(没地方可以下就是必败),必败态的上一层是必胜态(同,必胜态的上一层是必败态)。DFS一层一层往下推,若遍历完所有初始点,先手还是必败,则先手败(最优下法),否则后手败。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long ll;
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
struct Node{
    int x, y;
}rec[30];
int n, m, cnt;
char map[6][6];
int vis[6][6];
int DFS(int x, int y) {
    int flag = 0;
    for (int i =  0; i < 4; i++) {
        int px = x + dir[i][0], py = y + dir[i][1];
        if (px < 0 || py < 0 || px >= n || py >= m) continue;
        if (vis[px][py]) continue;
        if (map[px][py] == '*') continue;
        vis[px][py] = 1;
        if (DFS(px, py)) {
            flag = 1;
        } 
        vis[px][py] = 0;
    }   
    if (flag) return 0;
    else return 1;
}
int main() {
    while (scanf("%d %d\n", &n, &m) == 2) {
        memset(vis, 0, sizeof(vis));
        cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                scanf("%c", &map[i][j]);
                if (map[i][j] == '.') {
                    rec[cnt].x = i;
                    rec[cnt++].y = j;
                }
            }
            getchar();
        }
        int flag = 0 ;
        for (int i = 0; i < cnt; i++) {
            vis[rec[i].x][rec[i].y] = 1;
            if (DFS(rec[i].x, rec[i].y)) {
                flag = 1;
                break;
            }
            vis[rec[i].x][rec[i].y] = 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、付费专栏及课程。

余额充值