Codeforces Round #737 (Div. 2)

A. Ezzat and Two Subsequences

十年oi一场空,不开long long见祖宗

首先不难发现把最大数单独分为一组可以得到最大的一个f1.
简单证明一下这是最优解:
设除最大数外的的n-1个数平均数为m,
如果从中取出的数平均数大于m,显然f1和f2都减小
如果从中取出的数平均数等于m,则f1不变f2减小
如果从中取出的数平均数小于m,则。。。。。留给读者思考(逃

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 4e5 + 10;
const int inf = 1e9 + 10;
int T, n;
int a[maxn];

signed main() {
  cin >> T;
  while (T--) {
    int sum = 0, mx = -inf;
    cin >> n;
    for (int i = 1; i <= n; i++) {
      cin >> a[i];
      sum += a[i];
      mx = max(mx, a[i]);
    }
    double ans = 1.0 * (sum - mx) / (n - 1) + 1.0 * mx;
    printf("%.10lf\n", ans);
  }
  return 0;
}

B. Moamen and k-subarrays

题目中保证了n个数互异,不妨离散化为1~n
得到一个1~n的排列,你可以把它看成一条链,b1->b2->...->bn
通过把上面那条链切成若干段再以某种顺序拼起来,我们的目标是1->2->...->n
显然,如果一条边相连的两个数不是后面比前面大1,这条边就必须切开
如果一条边相连的两个数恰好是后面比前面大1,则无需切开(当然也可以切开)
于是最小的段数为 1 + 切开的次数,如果不大于k说明有解。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10;
int n, k, a[maxn], b[maxn];
int main() {
  int T;
  cin >> T;
  while (T--) {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i];
    sort(a + 1, a + 1 + n);
    int ans = 1;
    for (int i = 1; i <= n; i++) {
      b[i] = lower_bound(a + 1, a + 1 + n, b[i]) - a;
      if (i > 1 && b[i] != b[i - 1] + 1) ans++;
    }
    if (ans <= k) cout << "Yes" << endl;
    else cout << "No" << endl;
  }
  return 0;
}

hhh

posted @ 2021-08-18 17:34  _vv123  阅读(57)  评论(0编辑  收藏  举报