HDU 5040 Instrusive 【BFS+优先队列】

题意:你需要从M走到T,‘ # ’表示障碍不能走,‘ . ’表示道路,路上有W E N S的四种摄像头,每一秒钟会顺时针旋转一次,你拥有一个纸盒子(藏在纸盒子里不会被看到),你可以藏在纸盒子走需要花费3s,藏在纸盒子里原地不动1s,移动一步1s.到达T点所需要的时间。

思路:很容易想到  bfs+优先队列,如何记录状态呢,摄像头旋转周期的4,到达某一个点摄像头的状态只有4种状态,所以我们用VIS【X】【Y】【T%4】表示状态,我们还可以预处理摄像头照射的情况,然后就是bfs判断条件放入队列。

吐槽:什么鬼题意,揣摩了半天都没读懂。

///#include
///#include
///#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
const ll mod=998424353;
const int INF=0x3f3f3f3f;
const int maxn=1e5+5;

int n;
int vis[505][505][4];

int dic[4][2]= {1,0,-1,0,0,1,0,-1};

int num[5]={1,2,4,8,0};

int range[505][505];    ///记录位置被照射的情况
/// 二进制表示  1010表示t%4==3 和  t%4==1 被照射

char maps[505][505];

struct node
{
    int x;
    int y;
    int t;
    bool friend operator<(node a,node b)
    {
        return a.t>b.t;
    }
};

int win(int x,int y)
{
    if(x>=1&&x<=n&&y>=1&&y<=n&&maps[x][y]!='#')
        return 1;
    return 0;
}

int judge(int x,int y,int t)
{
    if(range[x][y]&num[t%4])    ///判断当前位置当前时刻是否被照射
        return 0;
    return 1;
}

int bfs(int sx,int sy)
{
    priority_queueq;
    memset(vis,0,sizeof(vis));
    vis[sx][sy][0]=1;
    q.push(node{sx,sy,0});
    while(!q.empty())
    {
        node now=q.top();
        q.pop();
        if(maps[now.x][now.y]=='T')
            return now.t;
        if(!vis[now.x][now.y][(now.t+1)%4])     ///在原地停留
        {
            vis[now.x][now.y][(now.t+1)%4]=1;
            q.push(node{now.x,now.y,now.t+1});
        }
        for(int i=0; i<=3; i++)
        {
            int dx=now.x+dic[i][0];
            int dy=now.y+dic[i][1];
            if(win(dx,dy))  ///下一个位置是否能够走
            {
                ///只走一步
                if(maps[dx][dy]!='W'&&maps[dx][dy]!='E'&&maps[dx][dy]!='N'&&maps[dx][dy]!='S')  ///下一个位置不是摄像头
                {
                    ///下一个位置未标记,并且  当前位置和下一个位置  没被监控
                    if(!vis[dx][dy][(now.t+1)%4]&&judge(now.x,now.y,now.t)&&judge(dx,dy,now.t))
                    {
                        ///比如t=0->t=1   (0,1],初始为S的摄像头,旋转过程中会一直监控(x+1,y)这一点
                        ///当t=1才监控到(x,y-1)
                        vis[dx][dy][(now.t+1)%4]=1;
                        q.push(node{dx,dy,now.t+1});
                    }
                }
                ///藏在盒子里走
                if(!vis[dx][dy][(now.t+3)%4])
                {
                    vis[dx][dy][(now.t+3)%4]=1;
                    q.push(node{dx,dy,now.t+3});
                }
            }
        }
    }
    return -1;
}

int main()
{
    int t;
    int sx,sy;
    scanf("%d",&t);
    for(int u=1; u<=t; u++)
    {
        memset(range,0,sizeof(range));
        scanf("%d",&n);
        for(int x=1; x<=n; x++)
        {
            scanf("%s",maps[x]+1);
            for(int y=1; y<=n; y++)
            {
                if(maps[x][y]=='W')
                {
                    range[x][y-1]|=num[0];
                    range[x-1][y]|=num[1];
                    range[x][y+1]|=num[2];
                    range[x+1][y]|=num[3];
                    range[x][y]=15;
                }
                else if(maps[x][y]=='E')
                {
                    range[x][y+1]|=num[0];
                    range[x+1][y]|=num[1];
                    range[x][y-1]|=num[2];
                    range[x-1][y]|=num[3];
                    range[x][y]=15;
                }
                else if(maps[x][y]=='N')
                {
                    range[x-1][y]|=num[0];
                    range[x][y+1]|=num[1];
                    range[x+1][y]|=num[2];
                    range[x][y-1]|=num[3];
                    range[x][y]=15;
                }
                else if(maps[x][y]=='S')
                {
                    range[x+1][y]|=num[0];
                    range[x][y-1]|=num[1];
                    range[x-1][y]|=num[2];
                    range[x][y+1]|=num[3];
                    range[x][y]=15;
                }
                else if(maps[x][y]=='M')
                    sx=x,sy=y;
            }
        }
        printf("Case #%d: %d\n",u,bfs(sx,sy));
    }
    return 0;
}

 

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