NYOJ 306

View Code
 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 }

 

posted @ 2012-05-07 21:51  知行执行  阅读(269)  评论(0编辑  收藏  举报