题目链接
M移动的是要完整的时间的,并且监控移动也是要完整的时间的,我们可以考虑前一刻的时间和后一刻的时间都要刚好遇不到监控的光、并且还不要在监控网格内才能往下走。所以,不妨看作是移动到下一个点是一个过程,把这段的时间都放在目前已经花费的一秒内,然后到下一个点的时候还要判断一下它的状态就行了(我认为判断状态不难,就是四种状态,是比较好想的,难想就在于监控的移动方式)。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 505;
//const int maxN = 12;
const int dir[4][2] =
{
-1, 0, //N
0, 1, //E
1, 0, //S
0, -1 //W
};
int N, sx, sy;
char mp[maxN][maxN];
bool vis[maxN][maxN][4], TLE[maxN][maxN][4];
struct node
{
int x, y, t;
node(int a=0, int b=0, int c=0):x(a), y(b), t(c) {}
friend bool operator < (node e1, node e2) { return e1.t > e2.t; }
};
priority_queue<node> Q;
int chi(char x)
{
if(x == 'N') return 0;
else if(x == 'E') return 1;
else if(x == 'S') return 2;
else if(x == 'W') return 3;
else return -1;
}
bool In_map(int x, int y) { return x>0 && y>0 && x<=N && y<=N; } //图内
int bfs(int x, int y)
{
while(!Q.empty()) Q.pop();
Q.push(node(x, y, 0));
memset(vis, false, sizeof(vis));
vis[x][y][0] = true;
while(!Q.empty())
{
node tmp = Q.top(); Q.pop();
if(mp[tmp.x][tmp.y] == 'T') return tmp.t;
if(!vis[tmp.x][tmp.y][(tmp.t + 1)%4]) Q.push(node(tmp.x, tmp.y, tmp.t + 1));
for(int i=0; i<4; i++)
{
int xx = tmp.x + dir[i][0], yy = tmp.y + dir[i][1], tt = tmp.t;
if(!In_map(xx, yy) || mp[xx][yy] == '#') continue;
if(TLE[xx][yy][tt%4] || TLE[tmp.x][tmp.y][tt%4]) tt += 3;
else tt += 1;
if(!vis[xx][yy][tt%4]) Q.push(node(xx, yy, tt));
vis[xx][yy][tt%4] = true;
}
}
return -1;
}
int main()
{
int T; scanf("%d", &T);
for(int Cas=1; Cas<=T; Cas++)
{
scanf("%d", &N);
memset(TLE, false, sizeof(TLE));
for(int i=1; i<=N; i++)
{
scanf("%s", mp[i] + 1);
for(int j=1; j<=N; j++)
{
if(mp[i][j] == 'M')
{
sx = i;
sy = j;
}
int tmp;
if( ( tmp = chi(mp[i][j]) ) != -1)
{
for(int k=0; k<4; k++)
{
int kk = (k + tmp)%4;
TLE[i][j][k] = true;
int xx = i + dir[kk][0], yy = j + dir[kk][1];
TLE[xx][yy][k] = true;
}
}
}
}
printf("Case #%d: %d\n", Cas, bfs(sx, sy));
}
return 0;
}
/*
2
3
M..
.N.
..T
3
M..
###
..T
ans:
5
-1
1
4
MS#.
..#.
.#E.
...T
ans:
7
*/