死亡洞穴
来源:互联网 发布:java工资待遇 编辑:程序博客网 时间:2024/04/28 10:49
Problem 117: 死亡洞穴
Time Limit:1 Ms| Memory Limit:64 MB
Difficulty:3
Description
在 caima 的 RPG 游戏中,控制着两个人 VV 和 JJ。
这次 VV 和 JJ 掉入了一个死亡洞穴,洞穴是一个 N*M 的矩阵。之所以称之
为死亡洞穴,是因为在这个矩阵中有一些死亡十字。(如下图中的+)
.....
.+++.
.+.+.
V+.J+
由于 VV 和 JJ 被分撒在了两地,而 JJ 还受了重伤,你需要让 VV 赶到 JJ 所
在的地方。为了尽量少的受死亡十字的影响,VV 要尽量远离这些死亡十字。
我们定义洞穴中两个格子(x,y)和(x’,y’)之间的距离为:|x-x'| + |y-y'|
也就是说,我们要使得 VV 再去找 JJ 的路上,离任意死亡十字的距离都尽
可能的远。VV 每次可以往一个格子的上下左右四个方向走一格。
现在你需要写个程序,来计算最好情况下离死亡十字最近的距离。
Input
第一行两个整数 N 和 M,表示矩阵规模。
接下来 N 行 M 列,描述这个洞穴的情况。其中
V 表示 VV 所在的位置;
J 表示 JJ 所在的位置;
. 表示空地;
+ 表示死亡十字。
Output
一行一个数字,表示 VV 在去找 JJ 的路上,最好情况下离死亡十字最近的距离。
Sample Input
4 4
+...
....
....
V..J
Sample Output
3
Hint
数据规模
对于 30% 的数据 N,M<=50。
对于 100% 的数据 N,M<=500。
Source
软件大赛
二分穷举距离时广搜:
Time Limit:1 Ms| Memory Limit:64 MB
Difficulty:3
Description
在 caima 的 RPG 游戏中,控制着两个人 VV 和 JJ。
这次 VV 和 JJ 掉入了一个死亡洞穴,洞穴是一个 N*M 的矩阵。之所以称之
为死亡洞穴,是因为在这个矩阵中有一些死亡十字。(如下图中的+)
.....
.+++.
.+.+.
V+.J+
由于 VV 和 JJ 被分撒在了两地,而 JJ 还受了重伤,你需要让 VV 赶到 JJ 所
在的地方。为了尽量少的受死亡十字的影响,VV 要尽量远离这些死亡十字。
我们定义洞穴中两个格子(x,y)和(x’,y’)之间的距离为:|x-x'| + |y-y'|
也就是说,我们要使得 VV 再去找 JJ 的路上,离任意死亡十字的距离都尽
可能的远。VV 每次可以往一个格子的上下左右四个方向走一格。
现在你需要写个程序,来计算最好情况下离死亡十字最近的距离。
Input
第一行两个整数 N 和 M,表示矩阵规模。
接下来 N 行 M 列,描述这个洞穴的情况。其中
V 表示 VV 所在的位置;
J 表示 JJ 所在的位置;
. 表示空地;
+ 表示死亡十字。
Output
一行一个数字,表示 VV 在去找 JJ 的路上,最好情况下离死亡十字最近的距离。
Sample Input
4 4
+...
....
....
V..J
Sample Output
3
Hint
数据规模
对于 30% 的数据 N,M<=50。
对于 100% 的数据 N,M<=500。
Source
软件大赛
思路:首先要预处理,初始化每个点到十字的最短距离,用作map,方法是广搜,遍历一下输入的整张图,遇到十字就进队列,然后作为开始广搜,搜到队列为空时,就实现了所有十字同步向外扩散,遍历一遍数组即全都初始化为距离十字的最小值。然后思路是从距离的大到小枚举,遇到最大的可以连通的就是答案,每次枚举一个距离,走大于等于这个距离的点。但是为了减少搜索次数,用二分的思想。深搜广搜都可以。另外,距离最大不会超过起点到十字的距离,因为若大于,起点都不能走。故二分的左边界是0,右边界是起点到十字的距离。
二分穷举距离时深搜:
#include<stdio.h>#include<string.h>#include<iostream>#include<queue> using namespace std; typedef struct{ int r, c; int step;}node; int ans, flag, mid, s_x, s_y, e_x, e_y;int n, m, map[505][505], vis[505][505];int dir[4][4] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};char temp[505][505]; void init();void init_bfs(int i, int j);void dfs(int r, int c);int main(){ int i, j, r, l; int Max, Min; scanf("%d %d", &n, &m); for(i = 0; i < n; i++) scanf("%s", temp[i]); init(); ans = 0; l = 0; r = map[s_x][s_y]; while(l <= r){ mid = (l + r) / 2; memset(vis, 0, sizeof(vis)); flag = 0; dfs(s_x, s_y); if(flag){ if(ans < mid) ans = mid; l = mid + 1; } else r = mid - 1; } printf("%d\n", ans); return 0;} void dfs(int r, int c){ if(r < 0 || r >= n || c < 0 || c >= m || vis[r][c] || map[r][c] < mid) return ; if(r == e_x && c == e_y){ flag = 1; return ; } vis[r][c] = 1; dfs(r - 1, c); dfs(r + 1, c); dfs(r, c - 1); dfs(r, c + 1);}void init(){ int i, j, k, row, col; node p, q; queue <node> Q; memset(vis, 0, sizeof(vis)); for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ if(temp[i][j] == '+'){ map[i][j] = 0; p.r = i; p.c = j; p.step = 0; vis[i][j] = 1; Q.push(p); } if(temp[i][j] == 'V'){ s_x = i; s_y = j; } if(temp[i][j] == 'J'){ e_x = i; e_y = j; } } } while(!Q.empty()){ q = Q.front(); Q.pop(); for(k = 0; k < 4; k++){ row = q.r + dir[k][0]; col = q.c + dir[k][1]; if(row >= 0 && row < n && col >= 0 && col < m && !vis[row][col]){ vis[row][col] = 1; p.r = row; p.c = col; p.step = q.step + 1; map[row][col] = p.step; Q.push(p); } } }}
二分穷举距离时广搜:
#include<stdio.h>#include<string.h>#include<iostream>#include<queue> using namespace std; typedef struct{ int r, c; int step;}node; int ans, flag, s_x, s_y, e_x, e_y;int n, m, map[505][505], vis[505][505];int dir[4][4] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};char temp[505][505]; void init();void init_bfs(int i, int j);void bfs(int mid);int main(){ int i, j, r, l, mid; int Max, Min; scanf("%d %d", &n, &m); for(i = 0; i < n; i++) scanf("%s", temp[i]); for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ map[i][j] = 65535; } } init(); ans = 0; l = 0; r = map[s_x][s_y]; while(l <= r){ mid = (l + r) / 2; memset(vis, 0, sizeof(vis)); flag = 0; bfs(mid); if(flag){ if(ans < mid) ans = mid; l = mid + 1; } else r = mid - 1; } printf("%d\n", ans); return 0;} void bfs(int mid){ int i, row, col; node p, q; queue <node> Q; p.r = s_x; p.c = s_y; vis[p.r][p.c] = 1; Q.push(p); while(!Q.empty()){ q = Q.front(); Q.pop(); if(q.r == e_x && q.c == e_y){ flag = 1; return ; } for(i = 0; i < 4; i++){ row = q.r + dir[i][0]; col = q.c + dir[i][1]; if(row >= 0 && row < n && col >= 0 && col < m && !vis[row][col] && map[row][col] >= mid){ vis[row][col] = 1; p.r = row; p.c = col; Q.push(p); } } }} void init(){ int i, j, k, row, col; node p, q; queue <node> Q; memset(vis, 0, sizeof(vis)); for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ if(temp[i][j] == '+'){ map[i][j] = 0; p.r = i; p.c = j; p.step = 0; vis[i][j] = 1; Q.push(p); } if(temp[i][j] == 'V'){ s_x = i; s_y = j; } if(temp[i][j] == 'J'){ e_x = i; e_y = j; } } } while(!Q.empty()){ q = Q.front(); Q.pop(); for(k = 0; k < 4; k++){ row = q.r + dir[k][0]; col = q.c + dir[k][1]; if(row >= 0 && row < n && col >= 0 && col < m && !vis[row][col]){ vis[row][col] = 1; p.r = row; p.c = col; p.step = q.step + 1; if(map[row][col] > p.step) map[row][col] = p.step; Q.push(p); } } }}
0 0
- 死亡洞穴
- 死亡洞穴
- 死亡
- 死亡
- 死亡
- 死亡
- 死亡
- 死亡
- 洞穴逃生
- 洞穴逃生
- 洞穴逃生
- 洞穴逃生
- 洞穴 Cave
- 洞穴探测
- [Sdoi2008]Cave 洞穴勘测
- Sicily 1754 逃离洞穴
- soj 1754. 逃离洞穴
- C++:洞穴逃生
- 重新开始战斗01-编程之美-象棋问题
- redis的安装及简单实用(Linux下)
- 云汇客写给未来骗子的信
- Java基础面试题与答案
- android开发中的一些用例
- 死亡洞穴
- Cocos2d-x C++写入文件
- poj 1915Knight moves
- UBUNTU12.04 安装ISE 12.2
- vs2008+Qt 编译MySQL驱动
- 语言和币种
- CC2430内置的温度传感器的说明
- spring中配置hibernate二级缓存
- PHP如何获取客户端真实IP