B - Blurred Pictures 二分+小细节(眼睛大)

题目:https://vjudge.z180.cn/contest/418003#problem/B

题意: 一个正方形相片,有1*1的像素构成的,但是损伤了一些像素,给出每一行像素从一个地方到另一个地方的没有损坏的像素,从中割除最大的没有损坏的正方形相片。

思路: 二分答案,判断答案是否可行,可行的话继续增大答案,否则减小答案;判断的过程是判断两侧是否满足自己二分的答案,有6种情况 (只列举最上面和最下面的横线)
1) …………
………… 这种情况不行
2) …………
………… 这种情况不行

3) ………… 判断相交的部分
…………

4)…………
………… 判断相交的部分
5) …………
……………………………… 判断相交的部分
6) ………………………………
………… 判断相交的部分

小细节: In any two consecutive lines, there are at least two non-blurred pixels in the same column.
用通俗的语言说就是这个没有损坏的像素是能连点一块的,并且它不是一个内凹的图形,只能往四周凸。 sush as
。。。。。。。
。。。。。
。。。。。。。 这样是不行的,因为有往里凹的图形。

代码:

#include <bits/stdc++.h>
#define lowbit(x) (x & (-x))
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e5 + 50;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int a[N], b[N], n;
inline bool Check(int k)
{
    
     
    for (int i = 0; i < n - k + 1; i++) {
    
      // 相距是k
        int l = i, r = i + k - 1; // 6 种情况
        if (b[r] < a[l] || a[r] > b[l]) continue;
        if (a[r] <= a[l]) {
    
    
            if (b[r] <= b[l]) {
    
    
                if (b[r] - a[l] + 1 >= k) return true;
            } else {
    
    
                if (b[l] - a[l] + 1 >= k) return true;
            }
        } else {
    
    
            if (b[r] <= b[l]) {
    
    
                if (b[r] - a[r] + 1 >= k) return true;
            } else {
    
    
                if (b[l] - a[r] + 1 >= k) return true;
            }
        }
    }
    return false;
}
int main()
{
    
    
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i] >> b[i];

    int ans = 0;
    int l = 1, r = 100000; // 二分答案
    while (l <= r) {
    
    
        int mid = (l + r) / 2;
        if (Check(mid)) {
    
    
            ans = mid;
            l = mid + 1;
        } else r = mid - 1;
    }

    cout << ans << endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/YingShen_xyz/article/details/112769803