HDU 1983 Kaitou Kid - The Phantom Thief (2) bfs and dfs

Description

破解字迷之后,你得知Kid将会在展览开始后T分钟内盗取至少一颗宝石,并离开展馆。整个展馆呈矩形分布,划分为N*M个区域,有唯一的入口和出口(不能从出口进入,同样不能从入口出去)。由某个区域可直接移动至相邻四个区域中的一个,且最快需要一分钟。假设Kid进入放有宝石的区域即可盗取宝石,无需耗时。问至少要封锁几个区域(可以封锁放有宝石的区域,但不能封锁入口和出口)才能保证Kid无法完成任务。

Input

输入的第一行有一个整数C,代表有C组测试数据。每组测试数据的第一行有三个整数N,M,T(2<=N,M<=8,T>0)。接下来N行M列为展馆布置图,其中包括:

‘S‘:入口 
‘E‘:出口 
‘J‘:放有宝石的区域,至少出现一次 
‘.‘:空白区域 
‘#‘:墙

Output

对每组测试数据,输出至少要封锁的区域数。

Sample Input

2

5 5 5

SJJJJ

..##J

.JJJJ

.J...

EJ...

5 5 6

SJJJJ

..##J

.JJJJ

.J... EJ...

Sample Output

0

2

这题既要用dfs,有要用bfs。dfs搜索要封锁的区域个数,bfs搜索Kid能否盗取宝石。很容易知道封锁的区域最多有4个,因为给入口或者出口围住最多只要4个区域,那么就可以给最大值设成4,然后去搜。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct p
{
    int x,y,t,su;
    int s1[90],s2[90];
};
int n,m,sx,sy,ans,time;
char map[10][10];
int v[10][10][2];
int yi[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
void dfs(int k)
{
    queue<p>q;
    p f,r;
    int vis=-1,i,j;
    if (k>ans) return ;
    f.x=sx;
    f.y=sy;
    f.t=0;
    f.su=0;
    memset(v,0,sizeof(v));
    while (!q.empty()) q.pop();
    v[sx][sy][0]=1;
    q.push(f);
    while (!q.empty())
    {
        r=q.front();
        q.pop();
        if (r.t>time) continue;
        if (map[r.x][r.y]==‘E‘&&r.su) {vis=r.t;break;}
        f.t=r.t+1;
        f.su=r.su;
        for (i=0;i<4;i++)
        {
            f.x=r.x+yi[i][0];
            f.y=r.y+yi[i][1];
            if (f.x>=0&&f.x<n&&f.y>=0&&f.y<m&&map[f.x][f.y]!=‘#‘)
            {
                if (map[f.x][f.y]==‘J‘) f.su=1;
                else f.su=r.su;
                if (v[f.x][f.y][f.su]) continue;
                v[f.x][f.y][f.su]=1;
                for (j=1;j<=r.t;j++)
                {
                    f.s1[j]=r.s1[j];
                    f.s2[j]=r.s2[j];
                }
                f.s1[f.t]=f.x;
                f.s2[f.t]=f.y;
                q.push(f);
            }
        }
    }
    if (vis==-1)
    {
        if (ans>k) ans=k;
        return ;
    }
    for (i=1;i<=r.t;i++)
    {
        char c=map[r.s1[i]][r.s2[i]];
        if (c==‘S‘||c==‘E‘) continue;
        map[r.s1[i]][r.s2[i]]=‘#‘;
        dfs(k+1);
        map[r.s1[i]][r.s2[i]]=c;
    }
}
int main()
{
    int c,i,j;
    scanf("%d",&c);
    while (c--)
    {
        scanf("%d%d%d",&n,&m,&time);
        for(i=0;i<n;i++)
        for(j=0;j<m;j++)
        {
            scanf(" %c",&map[i][j]);
            if (map[i][j]==‘S‘) {sx=i;sy=j;}
        }
        ans=4;
        dfs(0);
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-22 03:21:18

HDU 1983 Kaitou Kid - The Phantom Thief (2) bfs and dfs的相关文章

hdu 1983 Kaitou Kid - The Phantom Thief (2)

bfs+dfs很有意思也很好的一道题 然而我用了很久才ac #include<iostream> #include<cstring> #include<queue> using namespace std; char mapp[10][10]; int visit[10][10]; int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; int n,m,o; int sx,sy,ex,ey; int flag; struct stu { i

【HDOJ】1983 Kaitou Kid - The Phantom Thief (2)

不仅仅是DFS,还需要考虑可以走到终点.同时,需要进行预处理.至多封闭点数为起点和终点的非墙壁点的最小值. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <queue> 6 using namespace std; 7 8 typedef struct node_st { 9 int x, y, t, f

AGC31E Snuke the Phantom Thief

Snuke the Phantom Thief 有 \(N\) 个珠宝,第 \(i\) 个位于 \((x_i, y_i)\),价值为 \(v_i\).你可以选择一些珠宝,有若干限制,每个限制形如如下四种之一: \(x ≤ a_i\) 的珠宝只能选择不超过 \(b_i\) 个: \(x ≥ a_i\) 的珠宝只能选择不超过 \(b_i\) 个: \(y ≤ a_i\) 的珠宝只能选择不超过 \(b_i\) 个: \(y ≥ a_i\) 的珠宝只能选择不超过 \(b_i\) 个: 最大化选择的总价值

HDU 1253 胜利大逃亡 NYOJ 523【BFS】

胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 24608    Accepted Submission(s): 9427 Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的

【HDU 4771 Stealing Harry Potter&#39;s Precious】BFS+状压

2013杭州区域赛现场赛二水... 类似“胜利大逃亡”的搜索问题,有若干个宝藏分布在不同位置,问从起点遍历过所有k个宝藏的最短时间. 思路就是,从起点出发,搜索到最近的一个宝藏,然后以这个位置为起点,搜索下一个最近的宝藏,直至找到全部k个宝藏.有点贪心的感觉. 由于求最短时间,BFS更快捷,但耗内存,这道题就卡在这里了... 这里记录了我几次剪枝的历史...题目要求内存上限32768KB,就差最后600KB了...但我从理论上觉得已经不能再剪了,留下的结点都是盲目式搜索必然要访问的结点. 在此贴

HDU 5024 Wang Xifeng&#39;s Little Plot (bfs)

Problem Description <Dream of the Red Chamber>(also <The Story of the Stone>) is one of the Four Great Classical Novels of Chinese literature, and it is commonly regarded as the best one. This novel was created in Qing Dynasty, by Cao Xueqin.

HDU 2612 -Find a way (注意细节的BFS)

题目链接:Find a Way 题目不难,前几天做,当时准备写双向BFS的,后来处理细节上出了点问题,赶上点事搁置了,今天晚上重写的,没用双向,用了两次BFS搜索,和双向BFS 道理差不多,只是这题有个小坑,需要注意 1.Y不能经过M,M不能经过Y,也就是说有Y和M的格子,可以默认为是墙 2.必须是Y和M都能到达的KFC才行,只是其中一个到达不行 例如下列数据:答案既不是22 也不是 88 而是110,左下角的KFC满座条件 5 5 Y..#@ ...M. ....# ..... @.... 小

HDU 1142 A Walk Through the Forest(dijkstra+记忆化DFS)

题意: 给你一个图,找最短路.但是有个非一般的的条件:如果a,b之间有路,且你选择要走这条路,那么必须保证a到终点的所有路都小于b到终点的一条路.问满足这样的路径条数 有多少,噶呜~~题意是搜了解题报告才明白的Orz....英语渣~ 思路: 1.1为起点,2为终点,因为要走ab路时,必须保证那个条件,所以从终点开始使用单源最短路Dijkstra算法,得到每个点到终点的最短路,保存在dis[]数组中. 2.然后从起点开始深搜每条路,看看满足题意的路径有多少条. 3.这样搜索之后,dp[1]就是从起

HDU 1254 (经典游戏)推箱子 BFS+dfs

Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动. 现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格. Input 输入数据的第一行是一个整数T(1<=T<=20),代表测试