POJ 2110 Mountain Walking 二分+bfs

传送门

昨天看到这个题还以为是个脑残的dp, 然而脑残的是我。

题目意思就是从左上角走到右下角, 设x为路径上的最大值-最小值, 求x的最小值。

二分x, 对于每一个x, 枚举下界lower, lower从0开始枚举, 每一次bfs的时候, 如果一个点的值小于lower或者大于lower+x, 那么就不走这个点, 看最后能否走到终点。

自己的整数二分写的真是不忍直视...改了好久。

ps:poj2922貌似和这个一样

 1     #include<bits/stdc++.h>
 2     using namespace std;
 3     #define pb(x) push_back(x)
 4     #define ll long long
 5     #define mk(x, y) make_pair(x, y)
 6     #define lson l, m, rt<<1
 7     #define mem(a) memset(a, 0, sizeof(a))
 8     #define rson m+1, r, rt<<1|1
 9     #define mem1(a) memset(a, -1, sizeof(a))
10     #define mem2(a) memset(a, 0x3f, sizeof(a))
11     #define rep(i, a, n) for(int i = a; i<n; i++)
12     #define ull unsigned long long
13     typedef pair<int, int> pll;
14     const double PI = acos(-1.0);
15     const double eps = 1e-8;
16     const int mod = 1e9+7;
17     const int inf = 1061109567;
18     const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
19     int a[150][150], vis[120][120], n;
20     int bin(int lower, int upper) {
21         queue <pll> q;
22         mem(vis);
23         if(a[0][0]<lower||a[0][0]>upper)
24             return 0;
25         q.push(mk(0, 0));
26         vis[0][0] = 1;
27         while(!q.empty()) {
28             pll tmp = q.front(); q.pop();
29             int x = tmp.first;
30             int y = tmp.second;
31             if(x == n-1 && y == n-1)
32                 return 1;
33             for(int i = 0; i<4; i++) {
34                 int tmpx = x+dir[i][0];
35                 int tmpy = y+dir[i][1];
36                 if(tmpx>=0&&tmpx<n&&tmpy>=0&&tmpy<n&&!vis[tmpx][tmpy]) {
37                     vis[tmpx][tmpy] = 1;
38                     if(a[tmpx][tmpy]<=upper&&a[tmpx][tmpy]>=lower)
39                         q.push(mk(tmpx, tmpy));
40                 }
41             }
42         }
43         return 0;
44     }
45     int check(int val) {
46         for(int i = 0; i+val<=110; i++) {
47             if(bin(i, i+val))
48                return 1;
49         }
50         return 0;
51     }
52     int main()
53     {
54         while(cin>>n) {
55             for(int i = 0; i<n; i++) {
56                 for(int j = 0; j<n; j++) {
57                     scanf("%d", &a[i][j]);
58                 }
59             }
60             int l = 0, r = 110;
61             while(r>l) {
62                 int m = l+r>>1;
63                 if(check(m)) {
64                     r = m;
65                 } else {
66                     l = m+1;
67                 }
68             }
69             cout<<l<<endl;
70         }
71     }
原文地址:https://www.cnblogs.com/yohaha/p/5012373.html