比赛链接Dashboard - Codeforces Round 910 (Div. 2) - Codeforces
A
题意
给你一个长度为n的字符串,其中只含有A和B,你需要把它变成一个含有k个B的字符串,每次你能进行的操作是,选择一个位置,把这个位置之前的字符全部变成A或者B,求最小操作次数
思路
先判断原本字符串中B的数量,如果比k大,则需要把前面的B删掉,如果比k小,就需要把前面的A替换成B
ACcode
#include<iostream>
#include<string>
using namespace std;
void solve()
{
int n, k; cin >> n >> k;
int num = 0;
string str;
cin >> str;
for (int i = 0; i < n; i++) {
if (str[i] == 'B')num++;
}
if (num == k) { cout << 0 << '\n'; return; }
int result = 0;
if (num > k) {
num -= k;
for (int i = 0; i < n; i++) {
if (str[i] == 'B')result++;
if (result == num) {
cout << 1 << '\n';
cout << i+1<<' ' << 'A' << '\n'; return;
}
}
}
if (num < k) {
k -= num;
for (int i = 0; i < n; i++) {
if (str[i] == 'A')result++;
if (result == k) { cout << 1 << '\n'; cout << i + 1 << ' ' << 'B' << '\n'; return; }
}
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
B
题意
给你一个数列,需要把这个数列变成非递减数列,每次操作都用x和a[i]-x来替换x,问最小操作次数
思路
前面的数会影响后面的数,所以从后往前找,当a[i]>a[i+1]的时候开始操作,令x=a[i+1],为了保证非递减数列,最好要把a[i]分成a[i]/a[i+1](向上取整)份,而操作数是份数-1;
ACcode
#include<iostream>
using namespace std;
const int M = 2e5 + 9;
int a[M];
using ll = long long;
void solve()
{
int n; cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
ll ans = 0;
for (int i = n - 1; i > 0; i--) {
if (a[i] <= a[i + 1])continue;
int x = a[i + 1];
int y = (a[i] + x - 1) / x;//板子:a[i]是被除数,x是除数,且要求向上取整时
a[i] /= y;
ans += y - 1;
}
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
D
题目大意
给定登场的数列a,b,求每个对应位置差的绝对值的和的最大值,每组用例可以选择让b[i]和b[y]进行交换或者不交换
思路
计算每组a[i]-b[i],切换成计算每一组两个边界分别为a[i]和b[i]的线段长度和
由上图易知,当a1<b1<a2<b2且两条线段不相交的时候,交换后线段和会变大,且变大值是两倍的a2-b1
综上,我们需要找到最大的左边界和最小的右边界,当他们不相交的时候,叠加最大值
ACcode
#include<iostream>
#include<climits>
using namespace std;
const int M = 2e5 + 9;
int a[M], b[M];
using ll = long long;
void solve() {
int n; cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
for (int i = 1; i <= n; i++)cin >> b[i];
ll ans = 0;
ll mi = INT_MAX;
ll ma = 0;
for (int i = 1; i <= n; i++) {
ll le = min(a[i], b[i]);//小的是左边界
ll ri = max(a[i], b[i]);
ans += ri - le;
mi = min(ri, mi);
ma = max(le, ma);
}
if (ma>mi)ans += 2*(ma-mi);
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t; cin>> t;
while (t--) {
solve();
}
return 0;
}