题意:爬不同高度的山,尽量让最高和最低的跨度小
思路:二分枚举跨度,单纯的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;
}