HDU 1983:Kaitou Kid - The Phantom Thief (2)


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
 
   
2 5 5 5 SJJJJ ..##J .JJJJ .J... EJ... 5 5 6 SJJJJ ..##J .JJJJ .J... EJ...
 

Sample Output
 
   
0 2


#include 
#include 
#include 
#include 
#include 
#include 

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()
{
    queuequ;
    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


你可能感兴趣的:(ACM_搜索)