hdu 5040 Instrusive
Instrusive
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 596 Accepted Submission(s): 190
Problem Description
The legendary mercenary Solid Matt gets a classic mission: infiltrate a military base.
The military base can be seen as an N * N grid. Matt's target is in one of the grids and Matt is now in another grid.
In normal case, Matt can move from a grid to one of the four neighbor grids in a second. But this mission is not easy.
Around the military base there are fences, Matt can't get out of the base.
There are some grids filled with obstacles and Matt can't move into these grids.
There are also some surveillance cameras in the grids. Every camera is facing one of the four direction at first, but for every second, they will rotate 90 degree clockwisely. Every camera's sight range is 2, which means that if Matt is in the same grid as the camera, or in the grid that the camera is facing, he will be seen immediately and the mission will fail.
Matt has a special equipment to sneak: a cardbox. Matt can hide himself in the card box and move without being noticed. But In this situation, Matt will have to use 3 seconds to move 1 grid. Matt can also just hide in the cardbox without moving. The time to hide and the time to get out of the cardbox can be ignored.
Matt can't take the risk of being noticed, so he can't move without cardbox into a grid which is now insight of cameras or from a grid which is now insight of cameras. What's more, Matt may be in the cardbox at the beginning.
As a live legend, Matt wants to complete the mission in the shortest time.
The military base can be seen as an N * N grid. Matt's target is in one of the grids and Matt is now in another grid.
In normal case, Matt can move from a grid to one of the four neighbor grids in a second. But this mission is not easy.
Around the military base there are fences, Matt can't get out of the base.
There are some grids filled with obstacles and Matt can't move into these grids.
There are also some surveillance cameras in the grids. Every camera is facing one of the four direction at first, but for every second, they will rotate 90 degree clockwisely. Every camera's sight range is 2, which means that if Matt is in the same grid as the camera, or in the grid that the camera is facing, he will be seen immediately and the mission will fail.
Matt has a special equipment to sneak: a cardbox. Matt can hide himself in the card box and move without being noticed. But In this situation, Matt will have to use 3 seconds to move 1 grid. Matt can also just hide in the cardbox without moving. The time to hide and the time to get out of the cardbox can be ignored.
Matt can't take the risk of being noticed, so he can't move without cardbox into a grid which is now insight of cameras or from a grid which is now insight of cameras. What's more, Matt may be in the cardbox at the beginning.
As a live legend, Matt wants to complete the mission in the shortest time.
Input
The first line of the input contains an integer T, denoting the number of testcases. Then T test cases follow.
For each test cases, the first line contains one integer:N(1<=N<=500)
In the following N lines, each line contains N characters, indicating the grids.
There will be the following characters:
● '.' for empty
● '#' for obstacle
● 'N' for camera facing north
● 'W' for camera facing west
● 'S' for camera facing south
● 'E' for camera facing east
● 'T' for target
● 'M' for Matt
For each test cases, the first line contains one integer:N(1<=N<=500)
In the following N lines, each line contains N characters, indicating the grids.
There will be the following characters:
● '.' for empty
● '#' for obstacle
● 'N' for camera facing north
● 'W' for camera facing west
● 'S' for camera facing south
● 'E' for camera facing east
● 'T' for target
● 'M' for Matt
Output
For each test case, output one line "Case #x: y", where x is the case number (starting from 1) and y is the answer.
If Matt cannot complete the mission, output '-1'.
If Matt cannot complete the mission, output '-1'.
Sample Input
2
3
M..
.N.
..T
3
M..
###
..T
Sample Output
Case #1: 5
Case #2: -1
Source
题意:一张图,给出起点终点,障碍物以及摄像头,摄像头每秒钟转90度,求到达终点的最短时间。
思路:一开始想着建立500*500*4,用spfa,常数写搓果断TLE,后来改2m步后自动break,涉险400ms过关。后来发现×4的状态可以去掉,改完之后去掉break优化700ms。再改用优先队列,170ms。再改用各种方法,都没有能在170ms内跑完的。尽力了,不改了。下面贴代码。
1 /* 2 * Author: Joshua 3 * Created Time: 2014年09月21日 星期日 14时19分18秒 4 * File Name: 1009.cpp 5 */ 6 #include<cstdio> 7 #include<cstring> 8 #include<queue> 9 using namespace std; 10 #define maxn 520 11 #define inf 0x7f7f7f7f 12 typedef long long LL; 13 int T,n,sx,sy,ex,ey,kase; 14 char map[maxn][maxn]; 15 int dir[][2]={{-1,0},{0,1},{1,0},{0,-1}}; 16 int ce[maxn][maxn]; 17 int xm=511; 18 int d[maxn*maxn]; 19 bool f[maxn*maxn]; 20 21 struct cmp 22 { 23 bool operator()(int a,int b) 24 { 25 return d[a]>d[b]; 26 27 } 28 }; 29 30 void init() 31 { 32 scanf("%d",&n); scanf ("\n"); 33 for (int i=0;i<n;++i) 34 memset(ce[i],-1,4*n); 35 for (int i=0;i<n;++i) 36 { 37 scanf("%s",map[i]); 38 for (int j=0;j<n;++j) 39 { 40 if (map[i][j]=='M') sx=i,sy=j,map[i][j]='.'; 41 if (map[i][j]=='T') ex=i,ey=j,map[i][j]='.'; 42 if (map[i][j]=='N') ce[i][j]=0,map[i][j]='.'; 43 if (map[i][j]=='E') ce[i][j]=1,map[i][j]='.'; 44 if (map[i][j]=='S') ce[i][j]=2,map[i][j]='.'; 45 if (map[i][j]=='W') ce[i][j]=3,map[i][j]='.'; 46 } 47 } 48 int temp; 49 if (n<=100) 50 { 51 for (int i=0;i<n;++i) 52 for (int j=0;j<n;++j) 53 { 54 temp=(i<<9)+j; 55 d[temp]=inf; 56 f[temp]=false; 57 } 58 } 59 else 60 { 61 memset(d,0x7f,sizeof(d)); 62 memset(f,0,sizeof(f)); 63 } 64 } 65 66 void update(int x,int y,int dir,priority_queue<int, vector<int>,cmp> &q) 67 { 68 int temp=(x<<9)+y; 69 if (d[temp]>dir) 70 { 71 d[temp]=dir; 72 q.push(temp); 73 } 74 } 75 76 inline int fabs(const int &x) 77 { 78 if (x<0 ) return -x; 79 return x; 80 } 81 82 bool find(int tx,int ty,int tt ) 83 { 84 int xx,yy; 85 if (~ce[tx][ty]) return true; 86 for (int i=0;i<4;++i) 87 { 88 xx=tx+dir[i][0]; 89 yy=ty+dir[i][1]; 90 if (xx<0 || xx>=n || yy<0 || xx>=n) continue; 91 if (!(~ce[xx][yy])) continue; 92 if ( fabs( ((ce[xx][yy]+tt)&3)-i)==2) return true; 93 } 94 return false; 95 } 96 97 void solve() 98 { 99 int temp,tx,ty,tt,xx,yy,dis,end=(ex<<9)+ey; 100 bool flag; 101 priority_queue<int,vector<int>,cmp> q; 102 update(sx,sy,0,q); 103 while (!q.empty()) 104 { 105 temp=q.top(); 106 q.pop(); 107 if (f[temp]) continue; 108 if (temp==end) break; 109 f[temp]=true; 110 tx=(temp>>9)&xm; 111 ty=temp&xm; 112 dis=d[temp]; 113 tt=dis&3; 114 for (int i=0;i<4;++i) 115 { 116 flag=find(tx,ty,tt+i); 117 for (int l=0;l<4;++l) 118 { 119 xx=tx+dir[l][0]; 120 yy=ty+dir[l][1]; 121 if (xx<0 || xx>=n || yy<0 || yy>=n) continue; 122 if (map[xx][yy]=='#') continue; 123 if (flag || find(xx,yy,tt+i)) update(xx,yy,dis+i+3,q); 124 else update(xx,yy,dis+1+i,q); 125 } 126 } 127 } 128 int ans=inf; 129 if (d[end]<ans) 130 ans=d[end]; 131 if (ans==inf) ans=-1; 132 printf("Case #%d: %d\n",kase,ans); 133 } 134 135 int main() 136 { 137 scanf("%d",&T); 138 kase=0; 139 while (T--) 140 { 141 kase++; 142 init(); 143 solve(); 144 } 145 return 0; 146 }