UVALive-7297-Hounded by Indecision
2017-09-03 00:54
351 查看
题目链接:点击打开链接
题目大意:给你一个N*M的矩阵,里面有一个小偷,一个警察和一条警犬以及若干个出口,警察在追捕小偷。每次小偷和警察只能在水平或者竖直方向上移动一格,小偷和警察同时移动。起初警察和警犬在一起追捕,当警察到达小偷到达过的地点时,警犬则会以2倍的速度追赶小偷,而警察速度不变。问小偷能不能一定有办法在被追到之前离开矩阵。
解题思路:
题目就是让你搜索出口,并且看是否有方案满足不被警察追到。
其实我们只要解决如何判断某一个点能不能走,如果这个解决了,那么就依次判断下去就可以了,最后看是否可以到达出口。(记为A点)
一:收先可以判断的是小偷必须在警察之前到达A点(要保证一定不被抓),计小偷到A的时间为T1,警察到A点的时间为T2,则T2>T1;
二:满足条件一后,当小偷到达A点以后,由于当警察到达A点之后,警犬会以两倍的速度追赶,所以之后小偷又一个最大的移动时间。即超过该时间会被警犬追上。
计算该时间:当警察到达A点时(距离小偷离开A点已经有T2-T1的时间了),小偷领先警察T2-T1,之后警犬以小偷2倍的速度追赶,可以知道警犬会花费T2-T1的时间追上小偷。所以小偷到达A点以后最大的移动时间为Limit_Time=2*(T2-T1);
三:假设小偷在前一个点剩余的最大移动时间为T,那么在A点小偷的最大剩余移动时间为T-1,那么要保证不被警察抓到,在A点的剩余时间就应该取条件二与T-1的较小值,即Limit_Time=min(T-1,Limit_Time),然后每搜到一个点记录在该点的最大剩余时间。当重复搜到某个点时,如果后者可以使最大剩余时间变大(说明有更优的方案到达该点),则入队,并更新当前点最多剩余时间,否则不入队。
四:判断搜索。
代码:
#include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cstdio> #include<queue> using namespace std; char mp[55][55]; int xT,yT,xK,yK,n,m; int dir[4][2]={0,1,1,0,0,-1,-1,0}; int vis[55][55]; int Ksteps[55][55]; int Tsteps[55][55]; bool check(int x,int y){ if(x<0||x>n||y<0||y>m)return 0; return 1; } struct node{ int x,y; int steps; int Left_steps; }beg,in,out; void K_BFS(){ memset(Ksteps,-1,sizeof Ksteps); beg.x=xK;beg.y=yK;beg.steps=0; Ksteps[xK][yK]=0; queue<node>Q; Q.push(beg); while(!Q.empty()){ out=Q.front(); Q.pop(); for(int i=0;i<4;i++){ in.x=out.x+dir[i][0]; in.y=out.y+dir[i][1]; in.steps=out.steps+1; if(!check(in.x,in.y))continue; if(Ksteps[in.x][in.y]!=-1)continue; if(mp[in.x][in.y]=='X')continue; Ksteps[in.x][in.y]=in.steps; Q.push(in); } } } bool T_BFS(){ memset(Tsteps,0,sizeof Tsteps); beg.x=xT;beg.y=yT;beg.steps=0; beg.Left_steps=2*Ksteps[xT][yT]; Tsteps[xT][yT]=2*Ksteps[xT][yT]; queue<node>Q; Q.push(beg); while(!Q.empty()){ out=Q.front(); Q.pop(); if(mp[out.x][out.y]=='E')return true; for(int i=0;i<4;i++){ in.x=out.x+dir[i][0]; in.y=out.y+dir[i][1]; in.steps=out.steps+1; if(!check(in.x,in.y))continue; if(mp[in.x][in.y]=='X')continue; if(in.steps>=Ksteps[in.x][in.y])continue; in.Left_steps=min(out.Left_steps-1,2*Ksteps[in.x][in.y]-2*in.steps); if(in.Left_steps<=Tsteps[in.x][in.y])continue;//与该点的最大剩余做比较,变大才入队 Tsteps[in.x][in.y]=in.Left_steps; Q.push(in); } } return false; } int main(){ // freopen("in.txt","r",stdin); char ch; while(~scanf("%d%d",&m,&n)&&(n||m)){ getchar(); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ ch=getchar(); mp[i][j]=ch; if(ch=='T'){xT=i;yT=j;} if(ch=='K'){xK=i;yK=j;} } getchar(); } K_BFS(); if(T_BFS())printf("KEEP IT\n"); else printf("DROP IT\n"); } return 0; }开始写BFS()或者DFS()的题目的入门题的时候,感觉好像挺简单的(虽然现在的可能还是比较水,但是感觉不那么水了),就模板一套上去就可以了,然后就是什么BFS()+DFS()这类的,想想看也还好,接着碰到一些什么状态压缩(第一次碰到的时候)......卧槽!还有这种操作?!。总之搜索还是很灵活的,要好好体会。
相关文章推荐
- UVALive 7297 Hounded by Indecision BFS
- POJ1581 HDU1304 ZOJ1764 UVALive2832 A Contesting Decision【最值】
- UVALIVE 6958 I 求某TSP路径长度恰为定值+meet in middle + 折半
- UVALive 6092 - Catching Shade in Flatland(线段和圆交线段最大长度)
- UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点最近的点
- UVALive 6465 Islands in the Data Stream 暴力模拟
- UvaLive 6600 Spanning trees in a secure lock pattern 矩阵行列式
- UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点近期的点
- UvaLive 6600 Spanning trees in a secure lock pattern 矩阵行列式
- UVALive - 2728 A Spy in the Metro DP
- UVALive 6092 Catching Shade in Flatland --枚举+几何计算
- UVALive - 7267 Mysterious Antiques in Sackler Museum
- 2015北京邀请赛 UVALive7267 Mysterious Antiques in Sackler Museum
- UVALive 6092 Catching Shade in Flatland
- UVALive 7267 Mysterious Antiques in Sackler Museum 思维题 拼接矩形
- UVALive 4221 Walk in the Park 扫描线
- Islands in the Data Stream UVALive - 7092
- UVALive 7267 Mysterious Antiques in Sackler Museum (判断长方形)
- uvalive 6600 - Spanning trees in a secure lock pattern
- UVALive 4622 Decision(bfs)