Sum of Substrings
传送门 Problem - 1691C - Codeforces
题意
给定01序列,求出至多k次交换后最小的f(s).
思路
分类讨论。
1)在序列中间交换。
存在序列a1,a2,a3,a4.令a2,a3交换,那么将发生如下变化:
a1a2->a1a3;a2a3->a3a2;a3a4->a2a4.
显然当a2=a3时,不产生影响;假设a3=1,a2=0,那么产生的影响为1+9-10=0,不产生影响;反之a3=0,a2=1亦然。
2)在队头交换
存在序列a1,a2,a3.令a1,a2交换,那么将会发生如下变化:
a1a2->a2a1;a2a3->a1a3;
显然当a1=a2时不产生影响;假设a2=1,a1=0,那么产生9-10=-1的影响;反之产生+1影响。
2)在队尾交换
存在序列a1,a2,a3.令a2,a3交换,那么将会发生如下变化:
a1a2->a1a3;a2a3->a3a2;
显然当a1=a2时不产生影响;假设a2=1,a3=0,那么产生-1-9=-10的影响;反之产生+10的影响。
题目要求最小,那么只要去寻找能产生负的影响即可。另外,-10的优先级比-1高。先计算-10.
#include <bits/stdc++.h>
typedef long long ll;
#define all(a) (a).begin(), (a).end()
#define debug(a) cout <<#a << "=" << a << endl;
inline ll rr(){
ll f = 1, x = 0; char ch; do{ch = getchar(); if (ch == '-') f = -1; }while (ch < '0' || ch > '9'); do{x = x * 10 + ch - '0'; ch = getchar();}while (ch >= '0' && ch <= '9'); return f * x;
}
using namespace std;
const int maxn = 2e5 + 6;
int n, k;
int a[maxn];
string s;
int main(int argc, char const *argv[]) {
int t = rr();
while (t--) {
n = rr(), k = rr();
cin >> s;
int cnt = 0, sum = 0;
for (int i = 0; i < n - 1; i++) {
cnt = 0;
cnt += (s[i] == '1' ? 10 : 0), cnt += (s[i + 1] == '1' ? 1 : 0);
sum += cnt;
}
int pre = -1, suf = -1;
for (int i = 0; i < n; i++) {
if (s[i] == '1') {
pre = i;
break;
}
}
for (int i = n - 1; i >= 0; i--) {
if (s[i] == '1') {
suf = i;
break;}
}
if (~pre && pre == suf) {
if (k >= n - 1 - suf) {
std::cout << 1 << '\n';
continue;
}else if (k >= pre) {
std::cout << 10 << '\n';
continue;
}
}
if (~suf && suf != n - 1 && k >= n - 1 - suf) sum -= 10, k -= n - 1 - suf;
if (~pre && pre && k >= pre) sum -= 1, k -= pre;
std::cout << sum << '\n';
}
return 0;
}
使用C++解决Codeforces问题1691C:交换01序列

博客主要介绍了如何通过分类讨论解决Codeforces上的问题1691C,涉及01序列在不同位置交换后的效果分析。作者通过分析序列中间、队头和队尾交换的影响,提出了寻找负影响交换来达到最小目标值的策略,并给出了C++代码实现。
1396

被折叠的 条评论
为什么被折叠?



