死亡洞穴

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
預處理距離, 用二分法,最好情況下離死亡十字最近的距離,指的是走到終點的路徑中,相對長度最長的路徑, 求的是這個路徑中的最小值
符合條件就找更大的最低路徑 
#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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章