题解 P9457 [入门赛 #14] 魔法少女扶苏 (Hard Version)

Update on 2023/7/16 21:51 发现优先队列的英文写错了,已经更正。

分析

首先我们对于 ax,y 设需要至少进行 c 次操作才能满足 ax,yi=1nai,y+i=1max,i

进行 k 次操作后,需要满足:

ax,yci=1nai,ync+i=1max,imc

移一下项可以得到:

(n+m1)ci=1nai,y+i=1max,iax,y

因为 n+m1>0,所以又可以得到:

ci=1nai,y+i=1max,iax,yn+m1

所以:

c=i=1nai,y+i=1max,iax,yn+m1

接着对每一个进行计算,取第 k 小即可。

我用的是优先队列 std::priority_queue,时间复杂度 O(nmlogk)

代码

//the code is from chenjh
#include<cstdio>
#include<queue>
int n,m,k;
long long a[3003][3003],s[3003],q[3003];//s[i] 表示第 i 行的元素之和,q[j] 表示第 j 列的元素之和。
std::priority_queue<long long> Q;//建立一个大根堆。
// #define DEBUG 1  // 调试开关
struct IO {//快读快输,这一部分可以跳过。
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
  char buf[MAXSIZE], *p1, *p2;
  char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
  IO() : p1(buf), p2(buf), pp(pbuf) {}

  ~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
  char gc() {
#if DEBUG  // 调试,可显示字符
    return getchar();
#endif
    if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
    return p1 == p2 ? ' ' : *p1++;
  }

  bool blank(char ch) {
    return ch == ' ' || ch == '\n' || ch == '\r';
  }

  template <class T>
  void read(T &x) {
    x = 0;
    char ch = gc();
    for (; !isdigit(ch); ch = gc());
    for (; isdigit(ch); ch = gc()) x = x * 10 + (ch - '0');
  }

  void push(const char &c) {
#if DEBUG  // 调试,可显示字符
    putchar(c);
#else
    if (pp - pbuf == MAXSIZE) fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
    *pp++ = c;
#endif
  }

  template <class T>
  void write(T x) {
    if (x < 0) x = -x, push('-');  // 负数输出
    static T sta[35];
    T top = 0;
    do {
      sta[top++] = x % 10, x /= 10;
    } while (x);
    while (top) push(sta[--top] + '0');
  }

} io;

int main(){
    io.read(n),io.read(m),io.read(k);
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)io.read(a[i][j]),s[i]=s[i]+a[i][j],q[j]=q[j]+a[i][j];
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
        Q.push((s[i]+q[j]-a[i][j]+n+m-2)/(n+m-1));//因为要向上取整,所以要加上 n+m-2。
        while((int)Q.size()>k) Q.pop();超出 k,将堆顶弹出。
    }
    io.write(Q.top());//取出第 k 小。
    return 0;
}
posted @   Chen_Jinhui  阅读(32)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

一言

长大了,才能体会什么是责任!
——家庭
点击右上角即可分享
微信分享提示