Codeforces Round #638 (Div. 2)

Posted emcikem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #638 (Div. 2)相关的知识,希望对你有一定的参考价值。

A 贪心

(2 ^ k)组成数字,分成两份,每份(frac{n}{2})个数,求两份的最小差值
贪心策略,左边是最大值 + 前(frac{n}{2} - 1)个最小数,右边是中间的数

#include <iostream>
#include <cstdio>
#include <cmath>
#define ll long long
using namespace std;
ll x, y;
int main(){
	int t;
	cin >> t;
	while(t--){
		ll x = 0, y = 0;
		int n;
		cin >> n;
		for(int i = 1; i < n / 2; i++)
			x += 1ll << i;
		x += 1ll << n;
		for(int i = n / 2; i < n; i++)
			y += 1ll << i;
		printf("%lld
", x - y);
	}
	return 0;
}

B

C 贪心 + 字符串

把一个字符串分成k个非空字符串,最小化最大字典序,输出最大字典序
贪心策略,先把字符串排序,然后把取出前k个,每个字母为一个字符串,长度为1
那么如果说这k个字符有出现不同,比如a a a b ,那么最大字典序就是b了,字符串后面的字符直接放到a后面就行了
而这k个字符相同的话,观察发现,如果说后面的字符种类只有1个,那么平分后面的字符串给k个字符串即可,如aaabbbb分成3个,明显是abb,ab,ab合适
如果字符种类大于1个,那么把所有的剩余字符串放到任意个字符串即可。如aaabbc分成3个,明显是abbc,a,a比较合适

#include <iostream>
#include <cstdio>
#include <set>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1e5 + 5;
void solve(){
	int n, k;
	scanf("%d%d", &n, &k);
	string s;
	cin >> s;
	sort(s.begin(), s.end());
	if(k == 1){
		cout << s << endl;
		return;
	}
	string x[N];
	for(int i = 1; i <= k; i++)
		x[i] = s[i - 1];
	if(x[k][0] != x[1][0]){
		cout << x[k] << endl;
		return;
	}
	set<char>ss;
	for(int i = k; i < n; i++){
		ss.insert(s[i]);
	}
	if(ss.size() == 1){
		for(int i = 1; i <= ceil((n - k) / double(k)); i++)x[1] += s[k];
		cout << x[1] << endl;
	}else{
		cout << x[1] + s.substr(k, n - k) << endl;
	}
}
int main(){
	int T;
	cin >> T;
	while(T--)solve();
	return 0; 
}

D 贪心 + 二进制

有1个细菌质量为1,每天可以进行选择k个细菌进行等质量分裂,而每天晚上细菌会增加1个质量,求最小需要的时间,使得细菌总质量到达n
首先,如果是都不分裂,每晚加1,肯定能到达n。
考虑优化,分解1个质量为k的,那么数量 + 1,而质量 + 2,可以知道,分裂的增长量与质量无关,是选择分裂数目的2倍
那么如果全部都进行分裂,1,2,4,8,...,最后可能还剩下一个数字x
也就是说全部分裂的话还缺少x质量,那么考虑在分裂过程中,有一次分裂时有那么几个不分裂,使得这次分裂后质量 + x

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
void solve(){
	ll n;
	cin >> n;
	std::vector<ll> v;
	for(ll i = 1; i <= n; i *= 2){
		v.push_back(i);
		n -= i;
	}
	if(n > 0){
		v.push_back(n);
		sort(v.begin(), v.end());
	}
	cout << v.size() - 1 << endl;
	for(int i = 1; i < (int)v.size(); i++)
		cout << v[i] - v[i - 1] << " ";
	cout << endl;
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--)solve();
	return 0;
}

以上是关于Codeforces Round #638 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #638 (Div. 2)

Codeforces Round #638 (Div. 2)

Codeforces Round #638 (Div. 2)

Codeforces Round #638 (Div. 2)(A~B)

Codeforces Round #638 (Div. 2) A~C题解

CF A. Phoenix and Balance Codeforces Round #638 (Div. 2) 5月1号