zoukankan      html  css  js  c++  java
  • codechef [snackdown2017 Onsite Final] Minimax

    传送门

    题目描述

      考虑一个 N 行 N 列的网格,行列编号均为 1 ∼ N。每个格子中包含一个整数。记 ri 为第 i 行的最小值,Ci 为第 i 列的最大值。我们称一个网格为好的,当且仅当满足:$$max(r1, . . . , rN ) = min(C1, . . . , CN )$$

      大厨有这么一个网格,他可以将格子中的数字改为任意整数。请你告诉大厨,他至少需要改 变几个数字,才能使得网格变成好的。

    输入格式

      输入第一行,包含一个整数 N,代表网格的边长。 接下来 N 行,每行包含 N 个整数,代表每个格子中的整数。

    输出格式

      输出一个整数,代表最少需要改变的数字个数。

      这是Easy难度题啊qaq,那我大概只能回去刷beginner了。

      如果枚举一个最终k=max(ri)=max(li),那么代价就是一行内小于k的数字最少的数字数量加上一列内大于k的数字最少的数字数量,这样直接暴力是$O(n^4)$的。

      然后窝尝试三分k的值(因为看起来是单峰的嘛),结果好像并不行……

      回到暴力看一下,咦,这不是可以用堆优化一下嘛……复杂度$O(n^{2}logn)$

    被人看着写博客催颓废是一种什么样的感受……

    #include<queue>
    #include<cstdio>
    #include<cassert>
    #include<algorithm>
    #define fi first
    #define se second
    #define mp make_pair
    #define MN 1100
    using namespace std;
    
    struct na{int x,y;}p[1100000];
    int n,a[MN][MN],MMH=1e9,num=0,r[MN],c[MN];
    bool operator < (na x,na y){return a[x.x][x.y]<a[y.x][y.y];}
    priority_queue<pair<int,int> > R,C;
    int main(){
        scanf("%d",&n);
        
        for (int i=1;i<=n;i++) c[i]=n;
        for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        scanf("%d",&a[i][j]),p[++num].x=i,p[num].y=j;
        sort(p+1,p+1+num);
        for (int i=1;i<=n;i++) R.push(mp(0,i)),C.push(mp(-n,i));
        
        int _L=1,_R=1;
        for (int k=0;k<=1000000;k++){
            while (a[p[_R].x][p[_R].y]==k&&_R<=num) _R++;
            for (int i=_L;i<_R;i++) c[p[i].y]--,C.push(mp(-c[p[i].y],p[i].y));
            while (C.top().fi!=-c[C.top().se]) C.pop();
            while (R.top().fi!=-r[R.top().se]) R.pop();
            if (-C.top().fi-R.top().fi<MMH) MMH=-C.top().fi-R.top().fi;
            for (int i=_L;i<_R;i++) r[p[i].x]++,R.push(mp(-r[p[i].x],p[i].x));
            _L=_R;
        }
        
        printf("%d
    ",MMH);
    }
    View Code
  • 相关阅读:
    lintcode:previous permutation上一个排列
    lintcode : 二叉树的序列化和反序列化
    lintcode : find peak element 寻找峰值
    lintcode 中等题:搜索旋转排序数组II
    lintcode :搜索旋转排序数组
    lintcode: search for a range 搜索区间
    lintcode:最大子数组差
    lintcode:最大子数组II
    lintcode :最大子数组
    lintcode : 平衡二叉树
  • 原文地址:https://www.cnblogs.com/Enceladus/p/7120790.html
Copyright © 2011-2022 走看看