首页 > 代码库 > POJ - 2922 Honeymoon Hike

POJ - 2922 Honeymoon Hike

题意:爬不同高度的山,尽量让最高和最低的跨度小

思路:二分枚举跨度,单纯的DFS会超时

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 110;

int arr[MAXN][MAXN],vis[MAXN][MAXN],n;
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,1,-1};

int dfs(int x, int y, int a, int b){
	if (arr[x][y] > b || arr[x][y] < a)
		return 0;
	vis[x][y] = 1;
	if (x == n && y == n)
		return 1;
	if (x > n || y > n || x < 1 || y < 1)
		return 0;
	for (int i = 0; i < 4; i++){
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx < 1 || nx > n || ny < 1 || ny > n)
			continue;
		if (vis[nx][ny])
			continue;
		if (dfs(nx, ny, a, b))
			return 1;
	}
	return 0;
}

int search(int Min, int Max){
	int mid,tmp;
	while (Min < Max){
		mid = (Max+Min)>>1;
		tmp = arr[1][1]-mid;
		int i;
		for (i = tmp>0?tmp:0; i <= arr[1][1]; i++){
			memset(vis, 0, sizeof(vis));
			if (dfs(1, 1, i, i+mid))
				break;
		}
		if (i <= arr[1][1])
			Max = mid;
		else Min = mid+1;
	}
	return Max;
}

int main(){
	int t,cas=1;
	scanf("%d", &t);
	while (t--){
		scanf("%d", &n);
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				scanf("%d", &arr[i][j]);
		printf("Scenario #%d:\n", cas++);
		printf("%d\n\n", search(0, 200));
	}
	return 0;
}