Codeforces Round #638 (Div. 2)(C - Phoenix and Distribution D - Phoenix and Science题解)(训练)
2020-7-3
C - Phoenix and Distribution
题目大意:给你一个字符串s,将s的所有元素分成k个字符串,让所有字符串按字典序进行排序,问如何让在所有字符串中最大 的字符串的字典序最小。
解题思路:先对字符串s从小到大进行排序,分类讨论,分两类:1、第k个字符与第1个字符不相等(s[k-1]!=s[0]),则答案就是 s[k-1]。2、第k个字符与第1个字符相等(s[k-1]==s[0]),则再次分类讨论,a、第k+1个字符与最后一个字符相等则将从k+1到n的所有字符均分,输出s[k-1]和上面被均分后的s[i]。b、第k+1个字符与最后一个字符不相等,则输出s[k-1]。
代码
#include<bits/stdc++.h>
#define ll long long
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
string s;
int main()
{
int t,n,k;
cin>>t;
while(t--){
cin>>n>>k;
cin>>s;
sort(s.begin(),s.end());
if(s[k-1]!=s[0]){
cout<<s[k-1]<<endl;
}else{
if(s[k]!=s[n-1]){
for(int i=k-1;i<n;i++)cout<<s[i];
cout<<endl;
}else{
cout<<s[k-1];
int p=n-k;
for(int i=1;i<=p/k;i++)cout<<s[k];
if(p%k!=0)cout<<s[k];
cout<<endl;
}
}
}
return 0;
}
D - Phoenix and Science
(好题)
题目大意:给你一个质量为1的细胞,每天你可以选择其中几个分裂,也可以不分裂,每到夜晚每个细胞的质量都会增加1,给你一个数n,问你最短需要几天才能可以使其总质量等于n。
解题思路:贪心,用序列x 2的0次,2的1次,2的2次,2的3次…2的x次,组成sum,sum<=n。
1,sum==n,则该序列的长度就是最短天数,该序列的长度就是最短天数。
2,sum<n,则需要在该序列中插入元素sum-n,最短天数也是序列长度。
由于序列x是每次晚上所增加的质量,则每次白天所分裂的细胞数就是x[i+1]-x[i]。
代码
#include<bits/stdc++.h>
#define ll long long
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
vector<int>v;
int main()
{
int t,n;
cin>>t;
while(t--){
cin>>n;
v.clear();
for(int i=1;i<=n;i*=2){
//cout<<i<<" "<<n<<endl;
v.push_back(i);
n-=i;
}
if(n)v.push_back(n);
cout<<v.size()-1<<endl;
sort(v.begin(),v.end());
for(int i=0;i<v.size()-1;i++){
cout<<v[i+1]-v[i]<<" ";
}
printf("\n");
}
return 0;
}
越自律,越自由