题解:P12380 [蓝桥杯 2023 省 Python B] 管道

· · 题解

思路:

这题的思路是用二分答案来猜时间,在输出得到的答案即可,以下是集体步骤。

#include <bits/stdc++.h>
using namespace std;
long long n,len;
struct kok{
    long long L,S;
}a[100002];
int cmp(kok x,kok y){
    return x.S<y.S;
}
int check(long long mid){
    int tong[100002];
    for(int i=0;i<=len;i++){
        tong[i]=0;
    }
    for(int i=1;i<=n;i++){
        if(a[i].S<=mid){
            int l=a[i].L-(mid-a[i].S);
            int r=a[i].L+(mid-a[i].S);
            //cout<<mid<<" "<<l<<" "<<r<<endl;
            if(l<0)l=0;
            if(r>len)r=len;
            tong[l]++;
            tong[r+1]--;
        }
        else break;
    }
    for(int i=1;i<=len;i++){
        tong[i]+=tong[i-1];
    }
    int q=1;
    for(int i=1;i<=len;i++){
        if(tong[i]==0)q=0;
    }
    return q;
}
int main(){
    cin>>n>>len;
    for(int i=1;i<=n;i++){
        cin>>a[i].L>>a[i].S;
    }
    sort(a+1,a+1+n,cmp);
    long long l=0,r=1000000000;
    while(l+1<r){
        long long mid=(l+r)/2;
        if(check(mid)){
            r=mid;
        }
        else {
            l=mid;
        }
        //cout<<l<<" "<<r<<endl;
    }
    cout<<r;
    return 0;
}

正确代码要把桶来计数和前缀和改成下面一小段代码来计算检测到水流的传感器的数量。

    sort(b.begin(),b.end());
    int ans=0;
    for(auto p: b){
        int l=p.x,r=p.y;
        if(ans+1<l)
            return false;
        ans=max(ans,r);
    }
    return ans>=m;

以下是 python 代码。

def s():
    import sys
    i=sys.stdin.read
    d=i().split()
    x=0
    n,l=int(d[x]),int(d[x + 1])
    x+=2
    v=[]
    for _ in range(n):
        L, S = int(d[x]), int(d[x + 1])
        v.append((L, S))
        x += 2

    a = 0
    b = 2 * 10**18

    def c(t):
        r = []
        for L, S in v:
            if t >= S:
                d = t - S
                a = L - d
                b = L + d
                a = max(1, a)
                b = min(l, b)
                if a <= b:
                    r.append((a, b))
        if not r:
            return False
        r.sort()
        k = 0
        for a, b in r:
            if a > k + 1:
                return False
            k = max(k, b)
            if k >= l:
                return True
        return k >= l

    ans = b
    while a <= b:
        m = (a + b) // 2
        if c(m):
            ans = m
            b = m - 1
        else:
            a = m + 1
    print(ans)

s()