HDU 1728 逃离迷宫 (搜索)
来源:互联网 发布:python适合初学者的书 编辑:程序博客网 时间:2024/05/21 23:32
逃离迷宫
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 19550 Accepted Submission(s): 4747
Problem Description
给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
Input
第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。
Output
每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。
Sample Input
25 5...***.**...........*....1 1 1 1 35 5...***.**...........*....2 1 1 1 3
Sample Output
noyes
这题类似于Hdu1175,都存在一个最大的转弯次数上限。题目要求在达到转向次数上限前到达目的点,也就是求起始点到目的点的最少转向次数。
如果用行走步数来BFS,那么当存在多条起点至终点的最短路径时,会依据第一次搜索的结果做判定,也就是说在搜索正确路径前,如果先搜索了转弯数较多的最短路径,则会判定为错误,若重复搜索,则会极大地消耗内存,导致内存超限。所以将搜索最短路改为搜索转向次数最少的路径。也就是先搜索不转向可到达的点,再搜索一次转向可到达的点。以此类推。当搜索到目的点时,必定是转弯次数最小的路径。
如果使用DFS来写,则需要添加一个记忆数组来剪枝。如果在以前的搜索中曾访问过该点,则判断目前已转向次数是否大于或等于曾记录的值,若是,则不可能在在要求范围内到达终点,剪枝。
BFS代码:
#include<iostream>#include<string.h>#include<queue>#include<malloc.h>using namespace std;typedef struct P{ int x,y; int counts;} P;char a[105][105];int vis[105][105];const int dx[]= {1,0,-1,0};const int dy[]= {0,1,0,-1};int x1,y1,x2,y2,n,m,k;int judge(int x ,int y){ if(x>=1&&x<=n&&y>=1&&y<=m&&a[x][y]!='*') return 1; return 0;}int bfs(){ int i,nx,ny; queue<P>que; P p,tp; p.x = x1; p.y = y1; p.counts =-1; que.push(p); while(!que.empty()) { p = que.front(); que.pop(); if(p.counts>k) //如果出现转弯次数大于K,则代表无法在次数限制内到达终点 return 0; tp = p; tp.counts = p.counts+1; //从队列中取出后,一定会发生转向 for(i=0; i<4; i++) { nx = p.x + dx[i]; ny = p.y + dy[i]; while(judge(nx,ny)) //不发生转向,沿同一方向一直访问至尽头 { if(vis[nx][ny]==0) //当该地址未被访问才进入队列 { tp.x = nx; tp.y = ny; que.push(tp); vis[nx][ny]=1; } if(nx==x2&&ny==y2) { if(tp.counts<=k) return 1; else return 0; } nx = nx + dx[i]; ny = ny + dy[i]; } } } return 0;}int main(){ int t,i,j; cin>>t; while(t--) { cin>>n>>m; for(i=1; i<=n; i++) for(j=1; j<=m; j++) { cin>>a[i][j]; vis[i][j]=0; } cin>>k>>y1>>x1>>y2>>x2; vis[x1][y1]=1; if(bfs()) cout<<"yes"<<endl; else cout<<"no"<<endl; }}
DFS代码:
#include<iostream>#include<string.h>using namespace std;char a[105][105];int vis[105][105];int cmp[105][105];const int dx[]={1,0,-1,0};const int dy[]={0,1,0,-1};int x1,y1,x2,y2,n,m,k,flag;int judge(int x,int y){ if(x>=1&&x<=n&&y>=1&&y<=m&&a[x][y]=='.'&&vis[x][y]==0) return 1; return 0;}void dfs(int x,int y,int turn,int counts){ int i,nx,ny,tempturn,tempcounts; if(flag||counts>k||(counts==k&&(x!=x2&&y!=y2))) return; if(x==x2&&y==y2) { if(counts<=k) flag = 1; return; } tempturn=turn; tempcounts = counts; for(i=0;i<4;i++) { nx=x+dx[i]; ny=y+dy[i]; if(judge(nx,ny)) { if(cmp[nx][ny]==0||cmp[nx][ny]>counts) cmp[nx][ny]=counts; else if(cmp[nx][ny]<counts) continue; if(turn!=i&&turn!=-1) counts++; vis[nx][ny]=1; turn = i; dfs(nx,ny,turn,counts); vis[nx][ny]=0; turn = tempturn; counts = tempcounts; } }}int main(){ int t; cin>>t; while(t--) { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>a[i][j]; vis[i][j]=0; cmp[i][j]=0; } flag = 0; cin>>k>>y1>>x1>>y2>>x2; vis[x1][y1]=1; dfs(x1,y1,-1,0); if(flag) cout<<"yes"<<endl; else cout<<"no"<<endl; }}
以上
0 0
- HDU 1728 逃离迷宫 (搜索)
- HDU 1728 逃离迷宫(广度搜索)
- 搜索专题(DFS&&BFS&&剪枝)HDU 1728-逃离迷宫
- 逃离迷宫 HDU-1728 BFS深度搜索
- HDU 1728 逃离迷宫
- HDU 1728 逃离迷宫
- hdu 1728 逃离迷宫
- hdu 1728 逃离迷宫
- hdu 1728 逃离迷宫
- hdu 1728 逃离迷宫
- HDU-1728 逃离迷宫
- hdu 1728 逃离迷宫
- HDU 1728 逃离迷宫
- hdu 1728 逃离迷宫
- Hdu 1728 逃离迷宫
- hdu 1728 逃离迷宫
- HDU 1728 逃离迷宫
- hdu 1728 逃离迷宫
- mysql 使用
- 定位设备
- mysql 高可用 3
- codeforces 567D. One-Dimensional Battle Ships
- poj2109Power of Cryptography 大数开根
- HDU 1728 逃离迷宫 (搜索)
- cocos2d-js 取plist 数据
- web service 的概述(一)
- 设置软件开机自启动(C#实例演示)
- hdoj 1242 Rescue
- UVa 515 King (差分约束+线性规划+判负圈)
- Symmetric Tree
- Python伪装浏览器请求爬虫豆瓣小组
- Prim算法