zoukankan      html  css  js  c++  java
  • 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     }
  • 相关阅读:
    重写Override和重加载Overload
    Java 继承
    poj 3263 Tallest Cow
    矩阵求和
    全排列
    最大乘积
    三角形面积
    Sum
    搭积木
    调手表
  • 原文地址:https://www.cnblogs.com/yohaha/p/5012373.html
Copyright © 2011-2022 走看看