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号