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.
 

 

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
 

 

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'.
 

 

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 }

 

posted @ 2014-09-23 15:47  一个大叔  阅读(245)  评论(0编辑  收藏  举报