Loading

2022.10.24 总结

1. 逐月 P4988

逐月 P4988

题意

奶牛 Bessie 发表了 \(n\) 篇论文,并且她的第 \(i\) 篇论文被引用了 \(c_i\) 次。

现在有一个 \(h\) 指数,这个指数等于使得研究员有至少 \(h\) 篇引用次数不少于 \(h\) 的论文的最大整数。

Bessie 希望自己的 \(h\) 指数尽可能高,所以她写了一篇综述,在综述中,她只能引用 \(l\) 次,并且每篇论文最多只能被引用一次。

请你求出 Bessie 能达到的最大的 \(h\) 值。

思路

100 分

首先,先将 \(c\) 从大到小排序,所以 \(c\) 序列就变成了一个非递增序列,也就是 \(c_1 \ge c_2 \ge c_3 \ge \dots \ge c_n\)

然后,有两种情况:

  1. \(l = 0\)。因为 \(l = 0\),所以直接寻找 \(h\) 即可,而已经从大到小排过序了,直接找到最大的 \(c_h \ge h\) 即可。

  2. \(l \ne 0\)。在这种情况中,最后答案只有两种情况,\(h\)\(h + 1\)\(h\) 是前面\(l = 0\) 时的 \(h\))。首先,是 \(h\) 的情况很简单,就是上面那种。因为 \(c_{h + 1}\)\(\le h\) 的,而每篇文章只能引用一次,所以要么是 \(h\),要么是 \(h + 1\)

\(h\) 是可以直接求出来的,而 \(h + 1\) 则是由 \(1 \sim h + 1\) 中的所有 \(h\) 加上 \(1\) 的得到的,可以用循环求解,也可以先用桶记录。

时间复杂度

求出 \(h\)\(O(n)\)

循环求 \(h\) 的数量,\(O(n)\)。(用桶的话就没有)

总时间复杂度为 \(O(n)\)

空间复杂度

记录 \(c_i\)\(O(n)\)

用桶记录数量,\(O(\max \{c_i\})\)。(循环求解是没有的)

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int n, l, c[N], ans;

int main() {
  freopen("acowdemia1.in", "r", stdin);
  freopen("acowdemia1.out", "w", stdout);
  cin >> n >> l;
  for (int i = 1; i <= n; i++) {
    cin >> c[i];
  }
  sort(c + 1, c + n + 1);
  for (int i = 1; i <= n; i++) {
    if (c[n - i + 1] >= i) {
      ans = max(ans, i);
    } else {
      int ct = 0;
      bool f = 0;
      for (int j = n - i + 1; j <= n; j++) {
        if (i > c[j] + 1) {
          f = 1;
          break;
        }
        ct += (i > c[j]);
      }
      if (ct <= l && !f) {
        ans = max(ans, i);
      } else {
        break;
      }
    }
  }
  cout << ans;
  return 0;
}
posted @ 2023-03-02 22:45  chengning0909  阅读(9)  评论(0编辑  收藏  举报