Instrusive 【HDU - 5040】【2014北京网络赛】【BFS】

题目链接


  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
*/

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值