【算法系列学习】[kuangbin带你飞]专题二 搜索进阶 D - Escape (BFS)

Escape

参考:http://blog.csdn.net/libin56842/article/details/41909459

【题意】:
一个人从(0,0)跑到(n,m),只有k点能量,一秒消耗一点,在图中有k个炮塔,给出炮塔的射击方向c,射击间隔t,子弹速度v,坐标x,y
问这个人能不能安全到达终点
要求: 
1.人不能到达炮塔所在的坐标
2.炮塔会挡住子弹
3.途中遇到子弹是安全的,但是人如果停在这个坐标,而子弹也刚好到这个坐标,人就被射死
4.人可以选择停止不动
 
思路:其实不难,我们只需要看当人位于某个点的时候,其四个方向是否有炮塔,这个炮塔是都向人的方向射击,然后再看子弹是否刚好位于这个坐标即可。
而标记的话,vis[x][y][time],对于time时刻,人位于x,y的情况只需要访问一次,这是唯一的
 
【代码】
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<string>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<queue>
  8 
  9 using namespace std;
 10 int m,n,k,d;
 11 
 12 bool vis[1005][105][105];
 13 struct castle
 14 {
 15     int t,v;
 16     char c;
 17 }s[105][105];
 18 struct node
 19 {
 20     int x,y;
 21     int step;
 22     node(int xx,int yy,int ss):x(xx),y(yy),step(ss){}
 23 };
 24 
 25 int dir[5][2]={{1,0},{-1,0},{0,1},{0,-1},{0,0}};
 26 void Init()
 27 {
 28     memset(vis,0,sizeof(vis));
 29     memset(s,0,sizeof(s));
 30 }
 31 bool check(int x,int y)
 32 {
 33     if(x>=0&&x<=m&&y>=0&&y<=n)
 34     {
 35         return 1;
 36     }
 37     return 0;
 38 }
 39 void bfs()
 40 {
 41     queue<node> Q;
 42     Q.push(node(0,0,0));
 43     vis[0][0][0]=1;
 44     while(!Q.empty())
 45     {
 46         node q=Q.front();
 47         Q.pop();
 48         if(q.step>d)
 49         {
 50             printf("Bad luck!\n");
 51             return;
 52         }
 53         if(q.x==m&&q.y==n)
 54         {
 55             printf("%d\n",q.step);
 56             return;
 57         }
 58         for(int i=0;i<5;i++)
 59         {
 60             node to=q;
 61             to.x+=dir[i][0];
 62             to.y+=dir[i][1];
 63             to.step++;
 64             if(!check(to.x,to.y))
 65             {
 66                 continue;
 67             }
 68             if(!vis[to.step][to.x][to.y]&&!s[to.x][to.y].t)
 69             {
 70                 int life=1;
 71                 int dis;
 72                 //向北寻找
 73                 
 74                 for(int k=to.x-1;k>=0;k--)
 75                 {
 76                     if(s[k][to.y].t)
 77                     {
 78                         if(s[k][to.y].c=='S')
 79                         {
 80                             dis=to.x-k;
 81                             if(dis%s[k][to.y].v)
 82                             {
 83                                 break;
 84                             }
 85                             int tim=to.step-dis/s[k][to.y].v;
 86                             if(tim<0)
 87                             {
 88                                 break;
 89                             }
 90                             if(tim%s[k][to.y].t)
 91                             {
 92                                 break;
 93                             }
 94                             life=0;
 95                             break;
 96                         }
 97                         break;
 98                     }
 99                  }
100                  if(life)
101                  {
102                      //向南 
103                      for(int k=to.x+1;k<=m;k++)
104                     {
105                         if(s[k][to.y].t)
106                         {
107                             if(s[k][to.y].c=='N')
108                             {
109                                 dis=k-to.x;
110                                 if(dis%s[k][to.y].v)
111                                 {
112                                     break;
113                                 }
114                                 int tim=to.step-dis/s[k][to.y].v;
115                                 if(tim<0)
116                                 {
117                                     break;
118                                 }
119                                 if(tim%s[k][to.y].t)
120                                 {
121                                     break;
122                                 }
123                                 life=0;
124                                 break;
125                             }
126                             break;
127                         }
128                      }
129                   } 
130                   if(life)
131                  {
132                      //向东 
133                      for(int k=to.y+1;k<=n;k++)
134                     {
135                         if(s[to.x][k].t)
136                         {
137                             if(s[to.x][k].c=='W')
138                             {
139                                 dis=k-to.y;
140                                 if(dis%s[to.x][k].v)
141                                 {
142                                     break;
143                                 }
144                                 int tim=to.step-dis/s[to.x][k].v;
145                                 if(tim<0)
146                                 {
147                                     break;
148                                 }
149                                 if(tim%s[to.x][k].t)
150                                 {
151                                     break;
152                                 }
153                                 life=0;
154                                 break;
155                             }
156                             break;
157                         }
158                      }
159                   } 
160                   if(life)
161                  {
162                      //向西 
163                      for(int k=to.y-1;k>=0;k--)
164                     {
165                         if(s[to.x][k].t)
166                         {
167                             if(s[to.x][k].c=='E')
168                             {
169                                 dis=to.y-k;
170                                 if(dis%s[to.x][k].v)
171                                 {
172                                     break;
173                                 }
174                                 int tim=to.step-dis/s[to.x][k].v;
175                                 if(tim<0)
176                                 {
177                                     break;
178                                 }
179                                 if(tim%s[to.x][k].t)
180                                 {
181                                     break;
182                                 }
183                                 life=0;
184                                 break;
185                             }
186                             break;
187                         }
188                      }
189                   } 
190                   if(life)
191                   {
192                       vis[to.step][to.x][to.y]=1;
193                       Q.push(to);
194                   }
195                  
196             }
197             
198              
199         }
200     }
201     
202 }
203 int main()
204 {
205     while(~scanf("%d%d%d%d",&m,&n,&k,&d))
206     {
207         Init();
208     
209         for(int i=0;i<k;i++)
210         {
211             char c[3];
212             int t,v,x,y;
213             scanf("%s%d%d%d%d",c,&t,&v,&x,&y);
214             s[x][y].c=c[0];
215             s[x][y].t=t;
216             s[x][y].v=v;
217         }
218         bfs();
219     }
220     return 0;
221 }
BFS

【教训】

开始的时候是MLE,仔细查看了很久才反应过来,int vis[1005][105][105]数组开大了,1005*105*105/4/1000=44320kb,超出了题目限制32768kb,于是把int改成bool就A了。用sizeof操作符可以查看int占用4个字节,bool占用1个字节。以前做题从来不在意,都混着用.....以后还是要注意点....

posted @ 2017-04-01 13:28  shulin15  阅读(469)  评论(0编辑  收藏  举报