Problem 117: 死亡洞穴
Time Limit:1 Ms| Memory Limit:64 MB
Difficulty:3
Description
這次 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 列,描述這個洞穴的情況。其中
V 表示 VV 所在的位置;
J 表示 JJ 所在的位置;
. 表示空地;
+ 表示死亡十字。
Output
Sample Input
+...
....
....
V..J
Sample Output
#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;
}