HDU4101 Ali and Baba (bfs+dfs+博弈)

题意: Ali 和Baba玩游戏,游戏是在给出的一个n*m的图中,有且仅有一个宝藏(-1)表示,图中其他位置可能是空地(0表示),也可能是石头(石头的HP用一个正数表示)。二人轮流,每次游戏开始都是Ali先手,选手可以攻击石头,每次可以让石头HP减少一。问Ali是否可以胜利。

开始时,直接BFS 宝藏能扩展的最大的面积,因为面对都是1包围的-1 ,这个是必败态。但是WA了;然后想了很久,想到,可能存在宝藏所形成的连通的块是个环形,把其他的石头包围在里面,这样,这些石头就等于是没用的了。所以不得不多写了一个BFS_ans()

#include<bits/stdc++.h>
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define P pair<int,int>
#define X first
#define Y second
#define out(x) cout<<x<<endl;
using namespace std;
const int maxn=305;
const int inf=9999999;

int n,m;
int a[maxn][maxn];
bool vis[maxn][maxn];

int dir[][2]={{0,1},{1,0},{0,-1},{-1,0}};
bool pan(P s){
    if(s.X>=0&&s.X<=n+1&&s.Y>=0&&s.Y<=m+1)return true;
    return false;
}
void bfs(int x,int y){//标记宝藏形成的连通的块
    cl(vis,false);
    queue<P> q;
    q.push(P(x,y));
    vis[x][y]=true;
    while(!q.empty()){
        P s=q.front();q.pop();
        for(int i=0;i<4;i++){
            P tmp=s;
            tmp.X+=dir[i][0];
            tmp.Y+=dir[i][1];
            if(pan(tmp)&&!vis[tmp.X][tmp.Y]){
                vis[tmp.X][tmp.Y]=true;
                if(a[tmp.X][tmp.Y]==0)q.push(tmp);
            }
        }
    }
}
bool vis1[maxn][maxn];

int bfs_ans(){
    cl(vis1,false);
    queue<P> q;
    q.push(P(0,0));
    vis1[0][0]=true;
    int ans=0;
    while(!q.empty()){
        P s=q.front();q.pop();
        for(int i=0;i<4;i++){
            P tmp=s;
            tmp.X+=dir[i][0];
            tmp.Y+=dir[i][1];
            if(pan(tmp)&&!vis1[tmp.X][tmp.Y]){
                if(vis[tmp.X][tmp.Y]){
                    if(a[tmp.X][tmp.Y]>1)ans+=a[tmp.X][tmp.Y]-1;
                }
                else {
                    ans+=a[tmp.X][tmp.Y];
                    q.push(tmp);
                }
                vis1[tmp.X][tmp.Y]=true;
            }
        }
    }
    return ans;
}

bool used[maxn][maxn];
bool dfs(int x,int y){//查找是否存在一个直达的路径
    if(x==1||x==n||y==1||y==m){
        return true;
    }
    for(int i=0;i<4;i++){
        int xx=x+dir[i][0];
        int yy=y+dir[i][1];
        if(pan(P(xx,yy))&&!used[xx][yy]&&a[xx][yy]==0){

            used[xx][yy]=true;
            if(dfs(xx,yy))return true;
            //used[xx][yy]=false;
        }
    }
    return false;
}

int main(){

    while(~scanf("%d%d",&n,&m)){
        int si,sj;
        cl(a,0);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
                if(a[i][j]==-1){
                    si=i;sj=j;
                }
            }
        }

        if(si==1||si==n||sj==1||sj==m){
            puts("Ali Win");continue;
        }
        cl(used,0);
        if(dfs(si,sj)){
            puts("Ali Win");
            continue;
        }
        bfs(si,sj);
        //printf("===%d\n",bfs_ans());
        if(bfs_ans()&1){
            puts("Ali Win");
        }
        else {
            puts("Baba Win");
        }
    }
    return 0;
}
/*
4 4
1 1 1 1
1 1 0 1
1 1 -1 1
1 1 1 1
3 3
1 1 1
1 -1 1
1 1 1
4 4
1 1 0 1
1 1 0 1
1 1 -1 1
1 1 1  1
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 10:38:46

HDU4101 Ali and Baba (bfs+dfs+博弈)的相关文章

hdu 4101 Ali and Baba【BFS好题】

Ali and Baba Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2172    Accepted Submission(s): 460 Problem Description There is a rectangle area (with N rows and M columns) in front of Ali and Ba

(bfs+dfs) hdu 4101

Ali and Baba Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1799    Accepted Submission(s): 378 Problem Description There is a rectangle area (with N rows and M columns) in front of Ali and Bab

邻结矩阵的建立和 BFS,DFS;;

邻结矩阵比较简单,, 它的BFS,DFS, 两种遍历也比较简单,一个用队列, 一个用数组即可!!!但是邻接矩阵极其浪费空间,尤其是当它是一个稀疏矩阵的时候!!!---------------------------------------------------------------------------------------------------------------------------------------//邻接矩阵的建立和 其BFS, DFS, 遍历 #include <

HDU ACM 1044 Collect More Jewels BFS+DFS

题意:在一个迷宫中,有一些宝物,从起点走到终点,问在给定的时间内,到达终点后所能拾取珠宝的最大价值. 分析(BFS+DFS): 1.求入口到第一个取宝物的地方的最短距离 2.求第i个取宝物的地方到第i+1个取宝物的地方的最短距离 3.求第n个取宝物的地方到出口的最短距离 4.保证以上3点能在时间L内实现的情况下,取得的宝石价值最大. BFS特点:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元来存储状态) DFS特点:对于解决遍历和求所有问题有效,对于问

建图方式一 之 ”前向星“ BFS&amp;&amp;DFS 简单应用

三种建图方式,邻接矩阵.前向星(边表集).邻接链表! 耗时一晚上 ,好好研究了一下 前向星,因为我的指针用的实在是很烂,所以还是 入赘 前向星吧. 问了学长,看了大牛们的博客,终于有点收获了,个人认为 前向星Very Well. 前向星 建图方法: 以储存边的方式来储存图.在构造图时,把边存放在数组里,不需使用指针,只需一个 next  即可是整个图构建完成 . 适用条件: 点集特别多的稀疏图,边数多且繁杂,开邻接矩阵会浪费大量内存. 时间复杂度: O(m),并不比邻接链表差. #include

UVALive - 6455 Stealing Harry Potter&#39;s Precious (bfs+dfs)

https://cn.vjudge.net/problem/UVALive-6455 题目大意:题目上给出一个地图,其中@是人在地图上的出发点,#是墙,' . '是路.然后给出几个点,这些点表示财宝的所在地.问人是否能够得到所有的宝藏,如果能够的话给出所有的宝藏的最短的路径. 解题思路:由于只有最多4个宝藏所在地,所以只要用bfs找出出发点和财宝所在地距离到达其他点的步数.因为最多只有4个宝藏,所以可以暴力找出出发点到所有宝藏的最短距离. 暴力代码: 1 #include<stdio.h> 2

Collect More Jewels(hdu1044)(BFS+DFS)

Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6857    Accepted Submission(s): 1592 Problem Description It is written in the Book of The Lady: After the Creation, the cruel

hdu 4771 Stealing Harry Potter&#39;s Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: 目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离: 解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点  j 的距离: 然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的: AC代码: 1 #include<iostream>

POJ 1130(一道纯水,bfs+dfs)

POJ 1130 大概题意:给出一副图,求从起点到终点 (0->ET) 必须经过的一点. 我的思路:首先DFS求出经过每点的次数,必过的一点的次数一定最高,但是就这样吗?有可能有多个必过的点,所以还要找出离ET最近的点,这里就利用BFS逐层搜索的性质求每点到ET的距离. #include<iostream> #include<cstdio> #include<string.h> #include<iomanip> #include<queue&g