HDU5040-Instrusive (优先队列+BFS)

7 篇文章 0 订阅
7 篇文章 0 订阅

The legendary mercenary Solid Matt gets a classic mission: infiltrate a military base.

The military base can be seen as an N * N grid. Matt’s target is in one of the grids and Matt is now in another grid.

In normal case, Matt can move from a grid to one of the four neighbor grids in a second. But this mission is not easy.

Around the military base there are fences, Matt can’t get out of the base.

There are some grids filled with obstacles and Matt can’t move into these grids.

There are also some surveillance cameras in the grids. Every camera is facing one of the four direction at first, but for every second, they will rotate 90 degree clockwisely. Every camera’s sight range is 2, which means that if Matt is in the same grid as the camera, or in the grid that the camera is facing, he will be seen immediately and the mission will fail.

Matt has a special equipment to sneak: a cardbox. Matt can hide himself in the card box and move without being noticed. But In this situation, Matt will have to use 3 seconds to move 1 grid. Matt can also just hide in the cardbox without moving. The time to hide and the time to get out of the cardbox can be ignored.

Matt can’t take the risk of being noticed, so he can’t move without cardbox into a grid which is now insight of cameras or from a grid which is now insight of cameras. What’s more, Matt may be in the cardbox at the beginning.

As a live legend, Matt wants to complete the mission in the shortest time.
Input
The first line of the input contains an integer T, denoting the number of testcases. Then T test cases follow.

For each test cases, the first line contains one integer:N(1<=N<=500)

In the following N lines, each line contains N characters, indicating the grids.

There will be the following characters:

● ‘.’ for empty
● ‘#’ for obstacle
● ‘N’ for camera facing north
● ‘W’ for camera facing west
● ‘S’ for camera facing south
● ‘E’ for camera facing east
● ‘T’ for target
● ‘M’ for Matt
Output
For each test case, output one line “Case #x: y”, where x is the case number (starting from 1) and y is the answer.

If Matt cannot complete the mission, output ‘-1’.
Sample Input
2
3
M..
.N.
..T
3
M..

#

..T
Sample Output
Case #1: 5
Case #2: -1
题目:HUD5040
题意:给定一张图:
.-空地
#-墙
W,N,S,E-摄像机,以及摄像机第一秒所面对的方向
M-起点
T-终点
M执行任务要从起点到终点,但是地图上有一些摄像机,M在摄像机下走一格需要3S,在空地(.)上走一格需要1S,摄像机有一个初始朝向,此后每秒,摄像机顺时针转动90°,摄像机的监视范围为摄像机所在位置以及向面朝的方向延伸1格。

思路:根据题意,我们可以先把地图处理成四张子图,每张子图对应time%4时地图的状态,然后暴力搜索即可,注意,题目允许M待在原地,并且当M在摄像机下或者M走的下一步在摄像机下,花费的时间都应该为3S,标记时,我们对每个格子的4中状态分别标记即可。
忠告:不要修改原图,尽量开4张新图,内存不要钱啊,使劲造,不然BUG找到死。。。。
AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#define met(s,k) memset(s,k,sizeof s)
#define scan(a) scanf("%d",&a)
#define scanl(a) scanf("%lld",&a)
#define scann(a,b) scanf("%d%d",&a,&b)
#define scannl(a,b) scanf("%lld%lld",&a,&b)
#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define prin(a) printf("%d\n",a)
#define prinl(a) printf("%lld\n",a)
using namespace std;
typedef long long ll;
int dir[4][2]= {-1,0,0,1,1,0,0,-1};
int n,sx,sy,ex,ey;
char mp[4][515][515],mmp[515][515];
int ss[4][515][515];
struct node
{
    int x,y,t;
    friend bool operator< (node a,node b)
    {
        return a.t>b.t;
    }
};
int judge(int x,int y)
{
    if(x>=0&&x<n&&y>=0&&y<n)return 1;
    return 0;
}
void car(int i,int j)
{
    if(mmp[i][j]=='E')
    {
        mp[0][i][j]=mp[1][i][j]=mp[2][i][j]=mp[3][i][j]='*';
        if(judge(i,j+1))mp[0][i][j+1]='*';
        if(judge(i+1,j))mp[1][i+1][j]='*';
        if(judge(i,j-1))mp[2][i][j-1]='*';
        if(judge(i-1,j))mp[3][i-1][j]='*';
    }
    else if(mmp[i][j]=='S')
    {
        mp[0][i][j]=mp[1][i][j]=mp[2][i][j]=mp[3][i][j]='*';
        if(judge(i,j+1))mp[3][i][j+1]='*';
        if(judge(i+1,j))mp[0][i+1][j]='*';
        if(judge(i,j-1))mp[1][i][j-1]='*';
        if(judge(i-1,j))mp[2][i-1][j]='*';
    }
    else if(mmp[i][j]=='W')
    {
        mp[0][i][j]=mp[1][i][j]=mp[2][i][j]=mp[3][i][j]='*';
        if(judge(i,j+1))mp[2][i][j+1]='*';
        if(judge(i+1,j))mp[3][i+1][j]='*';
        if(judge(i,j-1))mp[0][i][j-1]='*';
        if(judge(i-1,j))mp[1][i-1][j]='*';
    }
    else if(mmp[i][j]=='N')
    {
        mp[0][i][j]=mp[1][i][j]=mp[2][i][j]=mp[3][i][j]='*';
        if(judge(i,j+1))mp[1][i][j+1]='*';
        if(judge(i+1,j))mp[2][i+1][j]='*';
        if(judge(i,j-1))mp[3][i][j-1]='*';
        if(judge(i-1,j))mp[0][i-1][j]='*';
    }
}
int bfs()
{
    node now,next;
    now.x=sx;
    now.y=sy;
    now.t=0;
    priority_queue<node>q;//优先队列,保证答案最小
    q.push(now);
    while(q.size())
    {
        now=q.top();
        if(now.x==ex&&now.y==ey)return now.t;
        next=now;
        next.t++;
        if(!ss[next.t%4][next.x][next.y])ss[next.t%4][next.x][next.y]=1,q.push(next);
        for(int i=0; i<4; i++)
        {
            next.x=now.x+dir[i][0];
            next.y=now.y+dir[i][1];
            if(judge(next.x,next.y)&&mmp[next.x][next.y]!='#')
            {
                if(mp[now.t%4][now.x][now.y]=='*'||mp[now.t%4][next.x][next.y]=='*')next.t=now.t+3;//如果当前,或者下一步在监视范围里,花费3S
                else next.t=now.t+1;
                if(!ss[next.t%4][next.x][next.y])
                {
                    ss[next.t%4][next.x][next.y]=1;
                    q.push(next);
                }
            }
        }
        q.pop();
    }
    return -1;
}
int main()
{
    int t;
    scan(t);
    for(int cas=1; cas<=t; cas++)
    {
        scan(n);
        met(ss,0);
        met(mp,0);
        for(int i=0; i<n; i++)scanf("%s",mmp[i]);
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(mmp[i][j]=='M')sx=i,sy=j,mmp[i][j]='.';
                else if(mmp[i][j]=='T')ex=i,ey=j,mmp[i][j]='.';
                else if(mmp[i][j]!='.'&&mmp[i][j]!='#')car(i,j);//存图
            }
        }
        printf("Case #%d: %d\n",cas,bfs());
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值