codeforces 910 div2(a,b,d)

比赛链接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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值