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 每次可以往一个格子的上下左右四个方向走一格。
现在你需要写个程序,来计算最好情况下离死亡十字最近的距离。
这次 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 所在的位置;
. 表示空地;
+ 表示死亡十字。
接下来 N 行 M 列,描述这个洞穴的情况。其中
V 表示 VV 所在的位置;
J 表示 JJ 所在的位置;
. 表示空地;
+ 表示死亡十字。
Output
一行一个数字,表示 VV 在去找 JJ 的路上,最好情况下离死亡十字最近的距离。
Sample Input
4 4
+...
....
....
V..J
+...
....
....
V..J
Sample Output
3
预处理距离, 用二分法,
最好情况下离死亡十字最近的距离,指的是走到终点的路径中,相对长度最长的路径, 求的是这个路径中的最小值
符合条件就找更大的最低路径
#include<iostream>
using namespace std;
#include<stdio.h>
#include<string.h>
#include<queue>
#define N 505
int low = 0, high, dir[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
char map[N][N];
int ha[N][N];
int dist[N][N];
int n, m;
int flag;
typedef struct{
int x, y;
}dot;
queue<dot> q;
dot start, end1;
void deal(){
int x, y, i;
dot e, near;
while(!q.empty()){
e = q.front();
q.pop();
// printf("%d\n", dist[e.x][e.y]);
for(i = 0; i < 4; i++){
x = e.x + dir[i][0];
y = e.y + dir[i][1];
if(x >= 0 && y >= 0 && x < n && y < m && ha[x][y] == 0){
ha[x][y] = 1;
dist[x][y] = 1 + dist[e.x][e.y];
near.x = x;
near.y = y;
if(x == start.x&& y == start.y){
high = dist[x][y];
}
q.push(near);
}
}
}
}
void dfs(dot e, int mid){
int x, y;
int i;
dot near;
if(e.x == end1.x && e.y == end1.y){
flag = 1;
return ;
}
for(i = 0; i < 4; i++){//find 4 directions whether can go head
x = e.x + dir[i][0];
y = e.y + dir[i][1];
if(x >= 0 && y >= 0 && x < n && y < m && dist[x][y] >= mid){
if(ha[x][y] == 0){
ha[x][y] = 1;
near.x = x;
near.y = y;
// printf("%d %d %d\n", x, y, dist[x][y]);
dfs(near, mid);
// ha[x][y] = 0;
}
if(flag == 1){
return ;
}
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int mid, last_dis = 0;
int i, j, z;
dot e;
char str[N];
scanf("%d%d", &n, &m);
getchar();//read char next be attention!!!!!
memset(dist, 0, sizeof(dist));
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
scanf("%c", &map[i][j]);
// printf("%c", map[i][j]);
if(map[i][j] == '+'){
e.x = i;
e.y = j;
ha[i][j] = 1;
q.push(e);
}
if(map[i][j] == 'V'){
start.x = i;
start.y = j;
}
if(map[i][j] == 'J'){
end1.x = i;
end1.y = j;
}
}
getchar();
//printf("\n");
}
deal();
while(low <= high){
flag = 0;
mid = (low + high) / 2;
// printf("%d\n", mid);
memset(ha, 0, sizeof(ha));
dfs(start, mid);
if(flag == 1){
low = mid + 1;
last_dis = mid;
}
else{
high = mid - 1;
}
}
printf("%d\n", last_dis);
/*做完每一步最好都打印验证一下, 不然会很惨!!*/
fclose(stdin);
//fclose(stdout);
return 0;
}