Codeforces Round 1014 (Div. 2) 补题

D. Mishkin Energizer

Problem - D - Codeforces

题意:给定一个只包含3个字母{T, L, I}的长度为n的字符串,可以进行最多2 * n次操作,每次操作选取一个位置i, 保证s[i] != s[i + 1], 然后插入一个 != s[i] && != s[i + 1]的字符,最后要保证每个字母出现的次数一样多,最后输出每次操作的位置,如果无法满足要求,输出-1

思路:首先特判这个字符串如果只有一种字符,那肯定是没有任何操作空间的。然后通过模拟, 假设此时的字符串是a  bbb, 那么第1个a和第1个b之间我是可以一直产生a和c的,最后变成acacabbb, 当这时候我们只有继续插入b,才能继续操作,所有我们可以发现,我们一定是优先让数量最小的字符尽可能的大,当我们数量第二小的字符和数量最多的字符数量一样时,我们就无法再操作了,接着只有插入数量最多的字符才能进行操作,至于这样操作为什么是保证 <= n * 2, 直接猜就完了^-^, 官方给的证明也没看懂.

总结:我们的模拟过程大致就是,先找到此时位置可以插入哪个字母,然后判断这个字母是不是数量最少的,是就插进去,如果我操作不了数量最小的字母,那就插入数量最多的字母,继续模拟,因为 n <= 100,所以每次模拟1遍插入1个字符慢慢来就可以

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#define int long long
using namespace std;

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int t;
	cin >> t;
	while(t --)
	{
		int n;
		cin >> n;
		string s;
		cin >> s;
		map<char,int> mp;
		vector<int> ans;
		vector<char> a {'L', 'I', 'T'};
		
		string tmp = s;
		sort(tmp.begin(), tmp.end());
		if(tmp[0] == tmp[tmp.size() - 1])
		{
			cout << -1 << '\n';
			continue;
		}
		
		for(int i = 0; i < s.size(); i ++)
		{
			mp[s[i]] ++;
		}
		
		auto get = [&](int u) -> char{
			for(int i = 0; i < a.size(); i ++)
			{
				if(a[i] != s[u] && a[i] != s[u + 1]) return a[i];
			}
			return '0';
		};
		
		while(max(mp['L'], max(mp['I'], mp['T'])) != min(mp['L'], min(mp['I'], mp['T'])))
		{
			bool f = false;
			int minn = min(mp['L'], min(mp['I'], mp['T']));
			int maxn = max(mp['L'], max(mp['I'], mp['T']));
			
			for(int i = 0; i < s.size() - 1; i ++)
			{
				char c = get(i); // 找到此位置可以插入的字符
				if(s[i] != s[i + 1] && mp[c] == minn)
				{
					f = true;
					mp[c] ++;
					s.insert(s.begin() + i + 1, 1, c);
					ans.push_back(i);
					break;
				}
			}
			if(!f) // 只能操作数量最多的字符
			{
				for(int i = 0; i < s.size() - 1; i ++)
				{
					char c = get(i);
					if(s[i] != s[i + 1] && mp[c] == maxn)
					{
						f = true;
						mp[c] ++;
						s.insert(s.begin() + i + 1, 1, c);
						ans.push_back(i);
						break;
					}
				}
			}
		}
		cout << ans.size() << '\n';
		for(auto i : ans) cout << i + 1 << '\n';
	}
	return 0;
}

C. Asuna and the Mosquitoes

Problem - C - Codeforces

题意:给定n个整数,每次选两个和为奇数的数,一个加1一个减1,让数组的最大值最大;

思路:通过模拟样例可以发现,奇数的个数永远是不变的,所以最大值就是吃掉所有偶数,再让本身外的奇数都变成1即可

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define int long long
using namespace std;

typedef pair<int,int> PII;

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int t;
	cin >> t;
	while(t --)
	{
		int n;
		cin >> n;
		vector<int> b;
		vector<int> c;
		for(int i = 0; i < n; i ++)
		{
			int x;
			cin >> x;
			if(x % 2) b.push_back(x);
			else c.push_back(x);
		}
		
		if(c.empty())
		{
			int maxn = 0;
			for(int i = 0; i < b.size(); i ++)
			{
				maxn = max(maxn, b[i]);
			}
			cout << maxn << '\n';
		}
		else if(b.empty())
		{
			int maxn = 0;
			for(int i = 0; i < c.size(); i ++)
			{
				maxn = max(maxn, c[i]);
			}
			cout << maxn << '\n';
		}
		else
		{
			sort(b.begin(), b.end());
			int ans = b[b.size() - 1];
			for(int i = 0; i < c.size(); i ++)
			{
				ans +=c[i];
			}
			for(int i = 0; i < b.size() - 1; i ++)
			{
				ans += b[i] - 1;
			}
			cout << ans << '\n';
		}
		
	}
	return 0;
}

B. Lady Bug

Problem - B - Codeforces

思路:根据题意画图,红色的线上都是可以互换的,蓝色的线上都是可以互换的,统计每一条线上0的个数即可

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define int long long
using namespace std;

typedef pair<int,int> PII;

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int t;
	cin >> t;
	while(t --)
	{
		int n;
		cin >> n;
		string a, b;
		cin >> a >> b;
		int cnt_a = 0; 
		int cnt_b = 0;
		for(int i = 0; i < n; i ++)
		{
			if(a[i] == '1') cnt_a ++;
			if(b[i] == '0') cnt_b ++;
		}
		if(cnt_a > cnt_b) cout << "NO" << '\n';
		else
		{
			int cnt1 = 0;
			int cnt2 = 0;
			a = " " + a;
			b = " " + b;
			for(int i = 1; i <= n; i ++)
			{
				if(i % 2)
				{
					if(a[i] == '0') cnt1 ++;
					if(b[i] == '0') cnt2 ++;
				}
				else
				{
					if(a[i] == '0') cnt2 ++;
					if(b[i] == '0') cnt1 ++;
				}
			}
			if(n % 2)
			{
				if(cnt1 >= n / 2 + 1 && cnt2 >= n / 2) cout << "YES" << '\n';
				else cout << "NO" << '\n';
			}
			else
			{
				if(cnt1 >= n / 2 && cnt2 >= n / 2) cout << "YES" << '\n';
				else cout << "NO" << '\n';
			}
		}
	}
	return 0;
}

A. Kamilka and the Sheep

Problem - A - Codeforces

思路:先根据样例猜一下结论,然后简单玩几个样例就可以发现了

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define int long long
using namespace std;

typedef pair<int,int> PII;

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int t;
	cin >> t;
	while(t --)
	{
		int n;
		cin >> n;
		vector<int>a(n, 0);
		for(int i = 0; i < n; i ++) cin >> a[i];
		sort(a.begin(), a.end());
		cout << a[n - 1] - a[0] << '\n';
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值