http://acm.hdu.edu.cn/showproblem.php?pid=5040
2 3 M.. .N. ..T 3 M.. ### ..T
Case #1: 5 Case #2: -1
/** hdu5040 优先队列+bfs 题目大意:给定一个n*n的图,从M走到T,#不能走,有一些照相机如果被照相机照住可以3秒一格的速度继续走或者停留1秒,照相机 只能找到其所在位置和它朝向的相邻一个格,并且没秒顺时针旋转90度,问最短的时间 解题思路:b[i][j][t%4]表示在ij点t秒时格子是否被照到,然后优先队列bfs就可以搞定了 */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> using namespace std; const int maxn=555; int n,xx1,xx2,yy1,yy2,vis[maxn][maxn][5],b[maxn][maxn][5]; int dx[][2]= {-1,0,1,0,0,-1,0,1,0,0}; char a[maxn][maxn]; struct note { int x,y,t; bool operator <(const note &other)const { return t>other.t; } }; int bfs() { // printf("%d %d,%d %d\n",xx1,yy1,xx2,yy2); memset(vis,0,sizeof(vis)); priority_queue<note>q; note tmp; tmp.x=xx1,tmp.y=yy1,tmp.t=0; q.push(tmp); vis[xx1][yy1][0]=1; while(!q.empty()) { tmp=q.top(); int x=tmp.x; int y=tmp.y; int t=tmp.t; // printf("t==%d\n",t); q.pop(); if(x==xx2&&y==yy2)return t; for(int i=0; i<5; i++) { int xx=x+dx[i][0]; int yy=y+dx[i][1]; if(xx<0||yy>=n||xx>=n||yy<0||a[xx][yy]=='#')continue; if(b[xx][yy][t%4]||b[x][y][t%4]) { if(xx==x&&yy==y&&!vis[xx][yy][(t+1)%4])///原地不动呆1秒 { vis[xx][yy][(t+1)%4]=1; tmp.x=xx,tmp.y=yy,tmp.t=t+1; q.push(tmp); } else if(!vis[xx][yy][(t+3)%4])///3秒一格走一格 { vis[xx][yy][(t+3)%4]=1; tmp.x=xx,tmp.y=yy,tmp.t=t+3; q.push(tmp); } } else if(!vis[xx][yy][(t+1)%4])///1秒一格走一格 { vis[xx][yy][(t+1)%4]=1; tmp.x=xx,tmp.y=yy,tmp.t=t+1; q.push(tmp); } } } return -1; } int main() { int T,tt=0; scanf("%d",&T); while(T--) { memset(b,0,sizeof(b)); scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%s",a[i]); for(int j=0; j<n; j++) { if(a[i][j]=='N') { b[i][j][0]=b[i][j][1]=b[i][j][2]=b[i][j][3]=1; if(i-1>=0)b[i-1][j][0]=1; if(j+1<n)b[i][j+1][1]=1; if(i+1<n)b[i+1][j][2]=1; if(j-1>=0)b[i][j-1][3]=1; } else if(a[i][j]=='E') { b[i][j][0]=b[i][j][1]=b[i][j][2]=b[i][j][3]=1; if(i-1>=0)b[i-1][j][3]=1; if(j+1<n)b[i][j+1][0]=1; if(i+1<n)b[i+1][j][1]=1; if(j-1>=0)b[i][j-1][2]=1; } else if(a[i][j]=='S') { b[i][j][0]=b[i][j][1]=b[i][j][2]=b[i][j][3]=1; if(i-1>=0)b[i-1][j][2]=1; if(j+1<n)b[i][j+1][3]=1; if(i+1<n)b[i+1][j][0]=1; if(j-1>=0)b[i][j-1][1]=1; } else if(a[i][j]=='W') { b[i][j][0]=b[i][j][1]=b[i][j][2]=b[i][j][3]=1; if(i-1>=0)b[i-1][j][1]=1; if(j+1<n)b[i][j+1][2]=1; if(i+1<n)b[i+1][j][3]=1; if(j-1>=0)b[i][j-1][0]=1; } else if(a[i][j]=='T') { xx2=i,yy2=j; } else if(a[i][j]=='M') { xx1=i,yy1=j; } } } printf("Case #%d: %d\n",++tt,bfs()); } return 0; }