HDU 4528 小明系列故事——捉迷藏
来源:互联网 发布:网络老虎机破解技巧 编辑:程序博客网 时间:2024/06/05 03:59
题目链接~~>
做题感悟:这题需要逆向思维,先预处理一下就好。
解题思路:先预处理一下将可以看到 D 与 E 的点标记一下,这样 bfs()遍历迷宫时就可以节省很多时间,还要注意:可以重复走走过的点只要用二进制压缩一下就好。
代码:
#include<stdio.h>#include<iostream>#include<map>#include<stack>#include<string>#include<string.h>#include<stdlib.h>#include<math.h>#include<vector>#include<queue>#include<algorithm>using namespace std ;#define lld __int64const double PI = 3.1415926 ;const double esp = 1e-4 ;const int md= 2810778 ;const int MX = 105 ;int n,m,t ;char s[MX][MX] ;bool va[MX][MX],vb[MX][MX],vis[MX][MX][5] ;int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1} ;struct node{ int x,y,step,key ;} ;bool search(int x,int y) // 判断边界{ if(x<0||y<0||x>=n||y>=m||s[x][y]=='X') return false ; return true ;}void init(int dx,int dy,int ex,int ey)// 预处理{ for(int i=dx+1 ;i<n ;i++) if(s[i][dy]=='.') va[i][dy]=true ; else if(s[i][dy]=='S') { va[i][dy]=true ; break ; } else break ; for(int i=dx-1 ;i>=0 ;i--) if(s[i][dy]=='.') va[i][dy]=true ; else if(s[i][dy]=='S') { va[i][dy]=true ; break ; } else break ; for(int j=dy+1 ;j<m ;j++) if(s[dx][j]=='.') va[dx][j]=true ; else if(s[dx][j]=='S') { va[dx][j]=true ; break ; } else break ; for(int j=dy-1 ;j>=0 ;j--) if(s[dx][j]=='.') va[dx][j]=true ; else if(s[dx][j]=='S') { va[dx][j]=true ; break ; } else break ; for(int i=ex+1 ;i<n ;i++) if(s[i][ey]=='.') vb[i][ey]=true ; else if(s[i][ey]=='S') { vb[i][ey]=true ; break ; } else break ; for(int i=ex-1 ;i>=0 ;i--) if(s[i][ey]=='.') vb[i][ey]=true ; else if(s[i][ey]=='S') { vb[i][ey]=true ; break ; } else break ; for(int j=ey+1 ;j<m ;j++) if(s[ex][j]=='.') vb[ex][j]=true ; else if(s[ex][j]=='S') { vb[ex][j]=true ; break ; } else break ; for(int j=ey-1 ;j>=0 ;j--) if(s[ex][j]=='.') vb[ex][j]=true ; else if(s[ex][j]=='S') { vb[ex][j]=true ; break ; } else break ;}int bfs(int x,int y){ memset(vis,false,sizeof(vis)) ; int sx,sy,key ; queue<node>q ; node curt,next ; curt.x=x ; curt.y=y ; curt.key=0 ; if(va[x][y]) curt.key=curt.key|1 ; if(vb[x][y]) curt.key=curt.key|2 ; curt.step=0 ; vis[x][y][curt.key]=true ; q.push(curt) ; while(!q.empty()) { curt=q.front() ; q.pop() ; if(curt.step>t) continue ; if(curt.key==3) // 判断是否找到两个人 return curt.step ; for(int i=0 ;i<4 ;i++) { next.x=sx=curt.x+dx[i] ; next.y=sy=curt.y+dy[i] ; next.key=key=curt.key ; next.step=curt.step+1 ; if(search(sx,sy)&&s[sx][sy]!='D'&&s[sx][sy]!='E') { if((key&1)==0&&va[sx][sy]) // 没看见过第一个人&&在这点可以看见第一个 key=key|1 ; if((key&2)==0&&vb[sx][sy]) // 没看见过第二个人&&在这点可以看见第二个人 key=key|2 ; if(!vis[sx][sy][key]) // 没有走过这点 { vis[sx][sy][key]=true ; next.key=key ; q.push(next) ; } } } } return -1 ;}int main(){ int Tx,q=1 ; scanf("%d",&Tx) ; while(Tx--) { scanf("%d%d%d",&n,&m,&t) ; int dx,dy,ex,ey,sx,sy ; for(int i=0 ;i<n ;i++) { scanf("%s",s[i]) ; for(int j=0 ;j<m ;j++) { if(s[i][j]=='D') { dx=i ; dy=j ; } else if(s[i][j]=='E') { ex=i ; ey=j ; } else if(s[i][j]=='S') { sx=i ; sy=j ; } } } memset(va,false,sizeof(va)) ; memset(vb,false,sizeof(vb)) ; init(dx,dy,ex,ey) ; printf("Case %d:\n%d\n",q++,bfs(sx,sy)) ; } return 0 ;}
0 0
- hdu 4528小明系列故事——捉迷藏
- BFS hdu-4528 小明系列故事——捉迷藏
- 【BFS】 HDU 4528 小明系列故事——捉迷藏
- HDU 4528 小明系列故事——捉迷藏
- hdu 4528 小明系列故事——捉迷藏
- hdu 4528 小明系列故事——捉迷藏【Bfs】
- 小明系列故事——捉迷藏
- 小明系列故事——捉迷藏
- hdu 4528——小明系列故事——捉迷藏
- hdu 4528小明系列故事——捉迷藏 (bfs)
- hdu 4528 小明系列故事——捉迷藏 bfs 解题报告
- HDU 4528 小明系列故事――捉迷藏
- hdu4528小明系列故事——捉迷藏(bfs)
- hdu4528 小明系列故事——捉迷藏 解题报告
- hdu4528 小明系列故事——捉迷藏
- HDU 4528 小明系列故事――捉迷藏 (很好的BFS)
- HDU 4506 小明系列故事——师兄帮帮忙
- hdu 4501 小明系列故事——买年货
- UNIX配置apue.h
- 图解String类型的不可变性及其原因
- 策略模式Strategy Pattern
- linux read write
- bbbb
- HDU 4528 小明系列故事——捉迷藏
- μC/OS-Ⅱ内核结构分析的七个问题
- 《iOS用户体验》总结与思考-修改版
- Linux at命令使用方法
- ORA-12154: TNS: 无法解析指定的连接标识符
- UVALive - 4513 Stammering Aliens(后缀数组模板)
- linux下使用find xargs grep查找文件及文件内容
- ubuntu常用软件包deb的安装与卸载
- hdu3080 The plan of city rebuild