1 条题解

  • 0
    @ 2025-8-24 21:54:17

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Anoxiacxy
    **

    搬运于2025-08-24 21:54:17,当前版本为作者最后更新于2017-10-21 16:17:39,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    对于这种最优化问题,我们可以二分答案啊,显然,最大值和最小值一定不被划分到一个区域里,那么我们假定最大值在矩形的上三角里,对于那些大于最大值减去我们二分的答案的数,都是符合要求的,然后判断不在当前区域的数,是不是都小于最小值加上我们二分的答案,由于最大值,最小值的位置不确定,所以我们可以把矩阵旋转四次,分别判断即可,只要有一种满足条件即可

    以下为英语短文填空裸题,后附参考答案

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define inf int(2e9)
    #define nl NULL
    using namespace std;
    int ___,____;int ______________=0,_____________=inf;
    int _________________[4][2017][2017],_______________=3;
    bool __________________[2017][2017];
    void ________(int ___________________,int ____________________){
        for(int _=1;_<=___;_++)
            for(int __=1;__<=____;__++)
                _________________[____________________][__][___-_ + 1]=_________________[___________________][_][__];
        swap(____ ,___);
    }
    bool _________(int ________________){
        int ____________=____;
        memset(__________________,0,sizeof(__________________));
        for(int _=1;_<=___;_++)
            for(int __=1;__<=____________;__++)
                if(_________________[_______________][_][__]+________________<______________){
                    ____________=__-1;break;
                }else __________________[_][__] = true;
        for(int _=___;_; _--)
            for(int __=____; __; __--)
                if(__________________[_][__])break;
                else if(_________________[_______________][_][__]-________________>_____________)return false;
        return true;
    }
    void ___________(){swap(___,____);_______________=(_______________+1)%4;}
    bool __________(int ________________){
        if(_________(________________)) return true; ___________();
        if(_________(________________)) return true; ___________();
        if(_________(________________)) return true; ___________();
        if(_________(________________)) return true; ___________();
        return false;        
    }
    int main(){
        scanf("%d%d",&___,&____);
        for(int _=1;_<=___;_++)for(int __=1;__<=____;__++){
            scanf("%d",&_________________[0][_][__]);
            ______________=max(______________,_________________[0][_][__]);
            _____________=min(_____________,_________________[0][_][__]);
        }
        ________(0,1);________(1,2);________(2,3);
        int _____=0,______=______________-_____________;
        while(_____<______){
            int _______=_____+______ >> 1;
            if(__________(_______))______=_______;
            else _____=_______+1;
        }
        printf("%d",_____);
    }
    

    参考答案

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define inf int(2e9)
    #define nl NULL
    using namespace std;
    int n,m;int maxv = 0, minv = inf;
    int a[4][2017][2017], coc = 3;
    bool f[2017][2017];
    void rotate(int s,int t){
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                a[t][j][n - i + 1] = a[s][i][j];
        swap(m ,n);
    }
    bool deal(int ans){
        int p = m;
        memset(f, 0, sizeof(f));
        for(int i = 1; i<= n; i++)
            for(int j = 1; j <= p; j++)
                if(a[coc][i][j] + ans < maxv){
                    p = j - 1; break;
                }else f[i][j] = true;
        for(int i = n; i; i--)
            for(int j = m; j; j--)
                if(f[i][j]) break;
                else if(a[coc][i][j] - ans > minv) return false;
        return true;
    }
    void nxt() {swap(n, m); coc = (coc + 1) % 4; }
    bool check(int ans){
        if(deal(ans)) return true;nxt();
        if(deal(ans)) return true;nxt();
        if(deal(ans)) return true;nxt();
        if(deal(ans)) return true;nxt();
        return false;        
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
            scanf("%d",&a[0][i][j]);
            maxv = max(maxv, a[0][i][j]);
            minv = min(minv, a[0][i][j]);
        }
        rotate(0, 1); rotate(1, 2); rotate(2, 3);
        int l = 0, r = maxv - minv;
        while(l < r){
            int mid = l + r >> 1;
            if(check(mid)) r = mid;
            else l = mid + 1;
        }
        printf("%d", l);
    }
    
    
    • 1

    信息

    ID
    2886
    时间
    1000~3000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者