1 /*
2 题外话:
3 这道题看了好久开始以为是动态规划,
4 但怎么也看不出怎么做。
5 今看别人的代码发现竟如此简短!
6 而且还是 DFS 原来这是一道深搜题
7 而且还用到了 二分查找
8 思路:
9 先得到 可能的最小差值:是 first = map[n][n]-map[1][1];
10 可能的最大差值是 last = 120(题中给的最大值)
11 取中间值 mid =(first + last)/2;
12 然后寻找 是否存在一条 最小差值是 mid 的路径
13 最在则 说明 可能最在比 mid 更小差值的路径
14 修改 last = mid;
15 若不存在 则 修改 first = mid+1 在
16 从新在(first,last)之间搜搜
17
18 在搜索时 我们假定 最小难度为 i (0<=i<=120)
19 则最大难度为 i+mid(i+mid<=120)
20 dfs(0,0,i,i+mid)朝四个方向搜
21 */
22
23 #include<iostream>
24 #include<cstdio>
25 #include<cstring>
26 using namespace std;
27
28 const int size = 101;
29
30 int map[size][size];
31 bool flag[size][size];
32 const int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
33 int n;
34
35 bool dfs(int x,int y,int low,int high)
36 {
37 int i;
38 if(x<1 || y<1 || x>n || y>n)return false;
39 if(map[x][y]<low || map[x][y]>high)return false;
40 if(flag[x][y])return false;
41 if(x==n && y==n)return true;
42 flag[x][y]=true;
43 for(i=0;i<4;++i)
44 if(dfs(x+dir[i][0],y+dir[i][1],low,high))return true;
45 return false;
46 }
47
48 bool slove(int mid)
49 {
50 int i;
51 for(i=0;i<=120-mid;++i)
52 {
53 memset(flag,0,sizeof(flag));
54 if(dfs(1,1,i,i+mid))return true;
55 }
56 return false;
57 }
58 int main()
59 {
60 int i,j,first,last,mid;
61 while(EOF != scanf("%d",&n))
62 {
63 for(i=1;i<=n;++i)
64 for(j=1;j<=n;++j)
65 scanf("%d",&map[i][j]);
66 first = map[n][n]-map[1][1];
67 if(first<0)first=-first;
68 last = 120;
69 while(first<last)
70 {
71 mid = (first + last)/2;
72 if(slove(mid))last=mid;
73 else first=mid+1;
74 }
75 printf("%d\n",first);
76 }
77 return 0;
78 }