【牛客周赛 Round 9】C D
https://ac.nowcoder.com/acm/contest/63869#question
C
https://ac.nowcoder.com/acm/contest/63869/C
题意
小美定义一个 01 串的权值为:每次操作选择一位取反,使得相邻字符都不相等的最小操作次数。
例如,"10001"的权值是 1,因为只需要修改一次:对第三个字符取反即可。
现在小美拿到了一个 01 串,她希望你求出所有非空连续子串的权值之和,你能帮帮她吗?
题解
1.暴力求 O(n^3) TLE
2.预处理 O(n^2) 仅枚举区间
code
点击查看代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
// const int N = 1e5 + 10;
int n;
char s[2005];
int a[2005], b[2005];
int fa[2005], fb[2005];
int main(){
scanf("%s", s + 1); n = strlen(s + 1);
a[0] = 0; b[0] = 1;
for(int i = 1; i <= n; i++) {
a[i] = (a[i - 1] ^ 1);
b[i] = (b[i - 1] ^ 1);
fa[i] = fa[i - 1] + (s[i] - '0' != a[i]);
fb[i] = fb[i - 1] + (s[i] - '0' != b[i]);
}
ll ans = 0;
for(int L = 1; L <= n; L++) {
for(int R = L; R <= n; R++) {
ans += min(fa[R] - fa[L - 1], fb[R] - fb[L - 1]);
}
}
printf("%lld\n", ans);
return 0;
}
D
https://ac.nowcoder.com/acm/contest/63869/D
题意
小美拿到了一个数组,她每次可以进行如下操作:
选择两个元素,一个加 1,另一个减 1。
小美希望若干次操作后,众数的出现次数尽可能多。你能帮她求出最小的操作次数吗?
题解
众数出现的次数,要么是 n,要么是 n-1.
是n的情况:平均数是整数,那么把所有数都变成平均数
是n-1的情况:先把数组排序,要么是前n-1个数的平均数,要么是后n-1个数
code
点击查看代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 10;
int n, a[N];
ll ans = 0;
int main(){
ios::sync_with_stdio(false);
cin >> n;
ll s = 0;
for(int i = 1; i <= n; i++) {
cin >> a[i]; s += a[i];
}
sort(a + 1, a + n + 1);
ll ave = s / n;
int more = s - 1ll * ave * n; // ave n-more ave+1 more
if(more == 0) {
for(int i = 1; i <= n; i++) {
if(a[i] < ave) ans += ave - a[i];
else break;
}
cout << ans << endl;
return 0;
}
ans = 1e18;
// 前n-1
ll tem = s - a[n]; tem /= (n - 1);
for(ll i = tem - 1; i <= tem + 1; i++) {
ll mn = 0, mx = 0;
for(int j = 1; j <= n - 1; j++) {
if(a[j] < i) mn += i - a[j];
else mx += a[j] - i;
}
ans = min(ans, max(mn, mx));
// cout << mn << ' ' << mx << ' ' << ans << endl; ///
}
// 后n-1
tem = s - a[1]; tem /= (n - 1);
for(ll i = tem - 1; i <= tem + 1; i++) {
ll mn = 0, mx = 0;
for(int j = 2; j <= n; j++) {
if(a[j] < i) mn += i - a[j];
else mx += a[j] - i;
}
ans = min(ans, max(mn, mx));
}
cout << ans << endl;
return 0;
}