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 }

 

你可能感兴趣的:(OJ)