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':放有宝石的区域,至少出现一次
'.':空白区域
'#':墙
'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
#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;
}