http://acm.hdu.edu.cn/showproblem.php?pid=5040
一个人拿着纸盒子往目的地走 正常情况下一秒走一格 可以原地不动躲在盒子里 也可以套着盒子三秒走一格
地图上有些灯 灯能照到自己和面前一个格 每一秒灯顺时针转90度 如果要从灯照的地方离开或者进入灯照的地方就必须套上盒子
最短时间到达
题意不清的bfs
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <bitset> #include <queue> #include <iostream> #include <algorithm> using namespace std; #define RD(x) scanf("%d",&x) #define RD2(x,y) scanf("%d%d",&x,&y) #define clr0(x) memset(x,0,sizeof(x)) typedef long long LL; const int maxn = 505; int sx,sy,n; int dx[] = {0,1,0,-1}, dy[] = {1,0,-1,0}; char s[maxn][maxn]; int dirr[128],notic[maxn][maxn]; bool vis[maxn][maxn][4]; bool in(int x,int y) { return 0 <= x && x < n && 0 <= y && y < n; } struct node{ int t,x,y; bool operator < (const node &a)const{ return t > a.t; } }; int bfs() { priority_queue <node> q; q.push((node){0,sx,sy}); while(!q.empty()){ node now = q.top(),to; q.pop(); if(s[now.x][now.y] == 'T'){ return now.t; } if(vis[now.x][now.y][now.t%4]) continue; vis[now.x][now.y][now.t%4] = true; to = now,to.t++; q.push(to); for(int i = 0;i < 4;++i){ int mx = now.x + dx[i],my = now.y + dy[i]; if(in(mx,my) && s[mx][my] != '#'){ //所在格子和目的格子同一秒没有摄像头的时候才能走 to.t = now.t + 1; if( (notic[mx][my] | notic[now.x][now.y]) & (1<<(now.t%4)) ) to.t = now.t + 3; to.x = mx,to.y = my; q.push(to); } } } return -1; } int main (){ int _,cas = 1; RD(_); dirr['E'] = 0,dirr['S'] = 1,dirr['W'] = 2,dirr['N'] = 3; dirr['T'] = dirr['M'] = dirr['.'] = dirr['#'] = -1; while(_--){ printf("Case #%d: ",cas++); RD(n); clr0(notic); clr0(vis); for(int i = 0;i < n;++i){ scanf("%s",s[i]); for(int j = 0;j < n;++j){ if(s[i][j] == 'M') sx = i,sy = j; else{ int now = dirr[ s[i][j] ]; if(now == -1) continue; notic[i][j] = (1<<4) - 1; for(int k = now;k < 4+now;++k){ int mx = i + dx[k%4],my = j + dy[k%4]; if(in(mx,my)){ notic[mx][my] |= (1<<(k-now)); } } } } } cout<<bfs()<<endl; } return 0; }