https://ac.nowcoder.com/acm/contest/20278/L
这题风格老cf了,首先考虑贪心,开数组记录每个字符出现的次数,将字母编号和对应出现次数纪录在结构体中,按次数多的排在前面贪心,
这里设结构体为p,id为对应字母,d为出现次数,从1到tot(tot为去重后的结构体个数)依次判定是否d还大于0,大于0则将其加到答案字符串里,并让d--,最后重复的肯定在结尾,例如cabcacc,按以上做法得到答案字符串cabcacc,末尾有多余c,但ab之间可以插个c,所以最后只需统计可插的位置及末尾多少重复即可,结合代码来看吧。
#include<bits/stdc++.h>
using namespace std;
const int N=100009;
struct Node{
int id,d;
}p[N];
int n;
int tot;
int M[N];
int b[N];
char s[N];
bool v[N];
int Max;
bool cmp(Node a,Node b){
return a.d>b.d;
}
int main()
{
cin>>n;
cin>>s;
for(int i=0;i<n;i++){
if(!v[s[i]-'a']){p[++tot].id=s[i]-'a',v[s[i]-'a']=1;M[tot]=s[i]-'a';}
b[s[i]-'a']++;
}
for(int i=1;i<=tot;i++)p[i].d=b[M[i]];
string ss="";
sort(p+1,p+1+tot,cmp);
while(1){
bool f=0;
for(int i=1;i<=tot;i++){
if(p[i].d>0){
p[i].d--;
ss+=p[i].id+'a';
f=1;
}
}
if(!f)break;
}
int cnt=0;
int k=ss.size();
for(int i=0;i<k-1;i++){
if(ss[i]==ss[i+1]){
cnt++;
}
}
if(cnt==0){
puts("yes");
cout<<ss<<endl;
return 0;
}
char ch=ss[k-1];
int sum=0;
for(int i=0;i<k-1;i++){
if(ss[i]!=ch&&ss[i+1]!=ch)sum++;
}
if(cnt>sum){puts("no");return 0;}
else{
puts("yes");
int g=cnt;
for(int i=0;i<k-g;i++){
cout<<ss[i];
if(ss[i]!=ch&&i+1<k-g&&ss[i+1]!=ch&&cnt>0){
cnt--;
cout<<ch;
}
}
}
return 0;
}

京公网安备 11010502036488号