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