【HDU 5040】Instrusive

来源:互联网 发布:vue.js左侧菜单栏 编辑:程序博客网 时间:2024/06/05 18:26

这道题在题意描述上让我很捉急,也可能是开这道题的时候已经进入了比赛的后半段,整个人也是感觉萌萌哒

因此在题意的理解方面出现了较大偏差

今天再把这道题翻出来做做,其实发现题意也没这么难理解

只要理解为:在1s之内,先是Matt动,然后再是探照灯动,再对状态进行分析就可以了

而我想到的是每一个格子有四种状态,分别是time % 4的情况,因为若time % 4的值相同则探照灯的朝向也是相同的

因此开个数组来记录一下就行了

在探照灯的照射方向方面,我想的是用一个数组cnot来记录当前位置什么时间有探照灯照射,这样就可以快速判断了

下面是代码:

#include<cstdio>#include<queue>#include<cstring>#include<algorithm>#define MM(a,b,c) memset(a,b,sizeof(a[0])*(c+2))using namespace std;const int dir[4][2] = {0,1,1,0,0,-1,-1,0};const int SIZEN = 505;char G[SIZEN][SIZEN];int sx,sy,tx,ty;int cnot[SIZEN][SIZEN];bool vis[SIZEN][SIZEN][4];int n,txt = 1;struct Stat{    int x,y;    int time;    bool operator < (const Stat &a)const{        return time > a.time;    }};void init(int n){    for(int i = 1 ; i <= n; i ++){        MM(cnot,0,n + 2);    }    memset(vis,0,sizeof(vis));}int idx(char c){    if(c == 'E') return 0;    else if(c == 'S') return 1;    else if(c == 'W') return 2;    else if(c == 'N') return 3;    return -1;}bool over(int x,int y){    if(x <= 0 || x > n) return 1;    if(y <= 0 || y > n) return 1;    return 0;}int bfs(){    priority_queue<Stat> Q;    Stat sp,p,tp;    sp.x = sx;sp.y = sy;    sp.time = 0;    Q.push(sp);    while(!Q.empty()){        p = Q.top();Q.pop();        if(G[p.x][p.y] == 'T') return p.time;        if(vis[p.x][p.y][p.time % 4]) continue;        vis[p.x][p.y][p.time % 4] = 1;        tp = p;        tp.time = p.time + 1;        Q.push(tp);        for(int i = 0 ; i < 4 ; i ++){            tp.x = p.x + dir[i][0];            tp.y = p.y + dir[i][1];            if(over(tp.x,tp.y)) continue;            if(G[tp.x][tp.y] == '#') continue;            tp.time = p.time + 1;            if(cnot[ p.x][ p.y] & (1ll << ((tp.time + 3) % 4))) tp.time = p.time + 3;            else if(cnot[tp.x][tp.y] & (1ll << ((tp.time + 3) % 4))) tp.time = p.time + 3;            Q.push(tp);        }    }    return -1;}void solve(){    scanf("%d",&n);    init(n);    for(int i = 1 ; i <= n ; i ++)        scanf("%s",G[i] + 1);    for(int i = 1 ; i <= n ; i ++)    for(int j = 1 ; j <= n ; j ++){        if(G[i][j] == 'M') sx = i,sy = j;        else if(G[i][j] == 'T') tx = i,ty = j;        else if(G[i][j] != '.' && G[i][j] != '#'){            int id = idx(G[i][j]);            cnot[i][j] = (1 << 4) - 1;            for(int k = id ; k < id + 4 ; k ++){                int nx = i + dir[k % 4][0];                int ny = j + dir[k % 4][1];                if(over(nx,ny)) continue;                cnot[nx][ny] |= (1 << ((k - id) % 4));            }        }    }    /*for(int i = 1 ; i <= n ; i ++){        for(int j = 1 ; j <=  n ; j ++) printf("%d ",cnot[i][j]);        printf("\n");    }*/    int ans = bfs();    printf("Case #%d: ",txt ++);    printf("%d\n",ans);}int main(){    int _;    scanf("%d",&_);    while(_--) solve();}/*12EM#T*/


0 0
原创粉丝点击