HDU 1983:Kaitou Kid

来源:互联网 发布:迪联软件 编辑:程序博客网 时间:2024/06/04 18:41


Kaitou Kid - The Phantom Thief (2)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1404    Accepted Submission(s): 525

点击打开链接
Problem 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
25 5 5SJJJJ..##J.JJJJ.J...EJ...5 5 6SJJJJ..##J.JJJJ.J...EJ...
 

Sample Output
02


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <math.h>#include <queue>using namespace std;const int MAXN = 10;char Map[MAXN][MAXN];int vis[MAXN][MAXN][2];/**本来想用vis来记录的三维是横坐标,纵坐标和到达该位置时的水晶数,那么第三维就应至少开64,但是想了想,水晶数大于1和等于1事实上等价,只要到达该位置获得过水晶就可以了。所以只用2维来进行标记**/int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};int C,N,M,T;int sx,sy,ex,ey;struct pos{    int x;    int y;    int flag;  ///用来标记到达该位置是否已经获得水晶    int time;  ///记录时间};bool BFS(){    queue<pos>qu;    pos now,nex;    memset(vis,0,sizeof(vis));    now.x = sx;    now.y = sy;    now.flag = 0;    now.time = 0;    vis[now.x][now.y][now.flag] = 1;    qu.push(now);    while(!qu.empty())    {        now = qu.front();        qu.pop();        if(now.time <= T)        {            if(now.x == ex && now.y == ey && vis[now.x][now.y][1])                return false;            if(now.time == T)                  continue;        ///时间最多为T,去考虑大于T的情况是没有什么意义的,不要花费宝贵时间去处理无用的情况        }        for(int i = 0; i < 4; i++)        {            nex.x = now.x + dir[i][0];            nex.y = now.y + dir[i][1];            nex.time = now.time + 1;            ///不能越界,不能是墙            if(nex.x<0 || nex.x>=N || nex.y<0 || nex.y>=M) continue;            if(Map[nex.x][nex.y] == '#') continue;            if(now.flag == 1 || Map[nex.x][nex.y] == 'J')              {                ///如果前一个位置已经拿到过水晶,或这个位置上有水晶。当前flag都置为1                nex.flag = 1;                if(vis[nex.x][nex.y][nex.flag]==0)                {                    vis[nex.x][nex.y][nex.flag] = 1;                    qu.push(nex);                }            }            else            {                nex.flag = now.flag;                if(vis[nex.x][nex.y][nex.flag]==0)                {                    vis[nex.x][nex.y][nex.flag] = 1;                    qu.push(nex);                }            }        }    }    return true;}bool dfs(int t){    if(!t) return BFS();    for(int i=0;i<N;i++)        for(int j=0;j<M;j++)        {            if(Map[i][j] == 'S' || Map[i][j]=='#' || Map[i][j]=='E') continue;            char ch = Map[i][j];            Map[i][j]='#';            if(dfs(t-1)) return true;            Map[i][j] = ch;        }    return false;}int main(){    scanf("%d",&C);    while(C--)    {        scanf("%d%d%d",&N,&M,&T);        for(int i = 0; i < N; i++)            for(int j = 0; j < M; j++)            {                scanf(" %c",&Map[i][j]);                if(Map[i][j] == 'S')                {                    sx = i; sy = j;                }                if(Map[i][j] == 'E')                {                    ex = i; ey = j;                }            }        if(BFS())            printf("0\n");        else        {            int flag = 1;            for(int i = 1; i < 4; i++)            {                if(flag)                {                    if(dfs(i))                    {                        printf("%d\n",i);                        flag = 0;                    }                }            }            if(flag)                printf("4\n");        }    }    return 0;}


0 0
原创粉丝点击