1 条题解

  • 0
    @ 2025-8-24 22:28:37

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar yeshubo_qwq
    我是 luxu。

    搬运于2025-08-24 22:28:37,当前版本为作者最后更新于2021-10-17 11:44:15,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题面


    Part1

    不难发现,此题的最小丑陋值(即答案)具有单调性,因此我们可以使用二分答案通过此题。

    既然使用二分,我们首先要做的就是确定边界:我们假设左鞋和右鞋各自有一只,分别为 1110000000001000000000,它们的丑陋值是 999999999999999999,即二分的上限;我们再假设左鞋和右鞋各自同样有一只,分别为 1111,它们的丑陋值是 00,即二分的下限

    接着套上二分模板。

    Code

    l=0;r=1e9;
    while(l<r){
        mid=(l+r-1)/2;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    

    Part2

    有了二分的边界,就只剩下二分的判定了。

    这里我用了双指针+贪心来实现。

    先求出哪种鞋子少,用并进行标记,左鞋标 11,右鞋标 00

    再给左、右鞋子各自从小到大排序(贪心思想)。

    接着就可以用双指针了,分成2类

      第1类:左鞋和右鞋指针指向的一双鞋符合条件(不超过要判断的数),左鞋和右鞋指针同时加一,组成的鞋子数量加一;  
      第2类:左鞋和右鞋指针指向的一双鞋不符合条件(超过要判断的数)指向鞋子数量多的指针加一; 
    

    最后判断组成的鞋子数是否达到要求即可。

    Code

    bool check(int x){
        int t=1,w=1,s=0;
        while(t<=n&&w<=m)
            if(abs(a[t]-b[w])<=x)t++,w++,s++;
            else if(flag)w++;//flag为标记
                else t++;
    	return s==cnt;//cnt为要求的鞋子数
    }
    

    最后贴上完整代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,cnt,flag,i,a[100010],b[100010],l,r,mid;
    bool check(int x){
        int t=1,w=1,s=0;
        while(t<=n&&w<=m)//双指针
            if(abs(a[t]-b[w])<=x)t++,w++,s++;
            else if(flag)w++;
                else t++;
        return s==cnt;
    }
    int main(){
        scanf("%d%d",&n,&m);
        cnt=min(n,m);//求出要求达到鞋子数
        if(cnt==n)flag=1;//进行标记
        else flag=0;
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        for(i=1;i<=m;i++)scanf("%d",&b[i]);
        sort(a+1,a+1+n);sort(b+1,b+1+m);//贪心
        l=0;r=1e9;
        while(l<r){//二分
            mid=(l+r-1)/2;
            if(check(mid))r=mid;
            else l=mid+1;
        }
        printf("%d",r);
    }
    

    求过

    • 1

    信息

    ID
    6414
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者