题意:你需要从M走到T,‘ # ’表示障碍不能走,‘ . ’表示道路,路上有W E N S的四种摄像头,每一秒钟会顺时针旋转一次,你拥有一个纸盒子(藏在纸盒子里不会被看到),你可以藏在纸盒子走需要花费3s,藏在纸盒子里原地不动1s,移动一步1s.到达T点所需要的时间。
思路:很容易想到 bfs+优先队列,如何记录状态呢,摄像头旋转周期的4,到达某一个点摄像头的状态只有4种状态,所以我们用VIS【X】【Y】【T%4】表示状态,我们还可以预处理摄像头照射的情况,然后就是bfs判断条件放入队列。
吐槽:什么鬼题意,揣摩了半天都没读懂。
///#include<bits/stdc++.h>
///#include<unordered_map>
///#include<unordered_set>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<bitset>
#include<set>
#include<stack>
#include<map>
#include<list>
#include<new>
#include<vector>
#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_queue<node>q;
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;
}