hdu1728 逃离迷宫(bfs限制拐弯次数)
来源:互联网 发布:thinkphp企业网站源码 编辑:程序博客网 时间:2024/04/28 20:24
http://acm.hdu.edu.cn/showproblem.php?pid=1728
题意:给你一张图,*代表墙,.代表路,给你起点终点坐标和限制的拐弯次数,求起点是否可以在拐弯次数内到达终点。
思路:经典的bfs。一般搜索题限制的是走的步数,而这题限制的是拐弯次数。按照我想的土办法,结构体里添加拐弯次数,每走一步判断是否拐弯,最后把能够到达终点的路线的拐弯次数统计下来求最小,看是否超过限制的拐弯次数。这样一方面内存多了不少,另外有了好多不必要的路,万一100x100中间没障碍物那路线数多的令人发指啊(最起码10000的几次方,不知道怎么算),必须剪枝,问题就来了,怎么减?统计拐弯次数求最小必须枚举所有的情况,剪个毛,那DP?对于这种路线问题我貌似只见过floyd还是最短路,行不通。想不到好的方案,所以参考了这位大牛。
别人的思路就是屌啊,既然是判断拐弯次数,那从起点开始索性把四个方向能走的路走到底,我们称之为1号十字(四个方向形象化),经过的节点全入队列。如果没有搜到,那么一号十字上的每个节点都可以在此基础(类似于树)上按出队顺序建立二号十字(也许不像十字,因为有边界和墙的限制,但本质还是十字,注意二号十字应该有多个),若还没有搜到,那么建立三号十字,如此往复。。每多一层十字,拐弯次数加一,由于是一层一层建立,所以一旦搜到即是最小拐弯数,直接比较即可。这样效率提高了非常多还不影响结果,根本思想感觉有点像树的层序遍历,但又不是,膜拜啊。
注意已经访问过的节点也能走,我们看下面这种情况。
我们知道1号线是红线,2号线是蓝线,3号线是绿线(不止一条),4号线是粉线。起点(1,1)终点(5,4)。(注意本题中横纵坐标反的,这里我们还是按照直观的坐标来说明)。可以看到,3号线由于墙挡着所以到不了终点,所以才会有4号线在三号线的基础上建立,但是第四行已经访问过了,所以把访问过的点经过,才可到达终点。(这图中虽然访问过的也能访问,但是重合的线我还是按照线序号小的优先画出,直观一点)。由于一号线也算方向但不算拐弯次数,所以初始化为-1。
整体来说这思路还是非常精辟,所以写了这么多。图纯手绘,别太吐槽哈~
#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>#include <queue>#include <stack>#include <ctype.h>using namespace std;typedef long long LL;const int N = 105;const int INF = 0x3f3f3f3f;char G[N][N];bool vis[N][N];int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};int n, m, limit, sx, sy, ex, ey;struct node{ int x, y, step;};bool check(int x, int y){ if(x>=1 && x<=m && y>=1 && y<=n && G[x][y]!='*') return true; else return false;}void bfs(int x, int y){ if(x==ex && y==ey) { printf("yes\n"); return; } memset(vis, false, sizeof(vis)); queue<node>que; node s; s.x = x; s.y = y; s.step = -1; vis[x][y] = true; que.push(s); while(!que.empty()) { node tmp = que.front(); que.pop(); for(int i = 0; i < 4; i++) { node tmp2; tmp2 = tmp; tmp2.x += dir[i][0]; tmp2.y += dir[i][1]; while(check(tmp2.x, tmp2.y)) { if(!vis[tmp2.x][tmp2.y]) { vis[tmp2.x][tmp2.y] = true; tmp2.step = tmp.step+1; if(tmp2.x == ex && tmp2.y == ey && tmp2.step<=limit) { printf("yes\n"); return; } que.push(tmp2); } tmp2.x += dir[i][0]; tmp2.y += dir[i][1]; } } } printf("no\n"); return;}int main(){ // freopen("in.txt", "r", stdin); int t; scanf("%d", &t); while(t--) { scanf("%d%d", &m, &n); for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) { cin >> G[i][j]; } scanf("%d%d%d%d%d", &limit, &sy, &sx, &ey, &ex); bfs(sx, sy); } return 0;}
- hdu1728 逃离迷宫(bfs限制拐弯次数)
- hdu1728逃离迷宫(bfs,拐弯问题)
- HDOJ 1728 逃离迷宫(BFS + 记录拐弯次数)
- HDOJ 1728 逃离迷宫(BFS,拐弯次数最少)
- hdu1728 逃离迷宫( bfs + 标记转向次数)
- HDU1728逃离迷宫(BFS)
- hdu1728逃离迷宫(BFS)
- hdu1728 逃离迷宫(bfs)
- HDU1728:逃离迷宫(BFS)
- hdu1728逃离迷宫(bfs)
- HDU1728:逃离迷宫(BFS)
- HDU1728 逃离迷宫 BFS
- hdu1728 逃离迷宫 bfs
- HDU1728 逃离迷宫 【BFS】
- HDU1728 逃离迷宫【BFS】
- hdu1728逃离迷宫 bfs
- HDU1728:逃离迷宫【BFS】
- HDU1728 逃离迷宫(BFS)
- qt 下载地址
- 求约束条件下极值的拉格朗日乘子法
- Python入门01
- 用kruskal方法做的
- The Question about Norm of Vector in MIMO
- hdu1728 逃离迷宫(bfs限制拐弯次数)
- 这周主讲面向对象,哈哈
- English考研句子第十句
- C语言经典算法02
- Python入门02
- JavaWeb初级学习 之 JavaScript
- 10.23
- Python入门03
- Codeforces 725C Hidden Word【思维+构造】