CF101A Homework题解
题目: 传送门
思路:
一边输入一边统计相同字母出现的次数,并统计出现了几个不同的字母。用结构体存储字母和该字母出现的次数,按照字母的出现次数由小到大排序,后用循环遍历。若设不同字母的数量为 \(t\) ,则循环的起点为 \(26-t+1\) (排除未出现的字母),终点为 \(26\) 。若某个字母的出现次数小于等于当前可删除的字母的数量(一定不要忘了等于!),则删除所有与这个字母相同的字母,用一个 \(bool\) 数组统计某个字母是否被删除。输出时按初始顺序遍历输入的字符串(以保证输出的是输入字符串的子序列),若 \(bool\) 数组显示该字母未被删除,则输出该字母。(详见代码)
代码:
#include <bits/stdc++.h>
using namespace std;
char c[100005];
int n,l,t,i,j;
bool b[30];
struct xy{
char x;
int y;
}a[30];
bool cmp(xy u,xy v)
{
return u.y<v.y;
}
int main()
{
scanf("%s",&c);
scanf("%d",&n);
l=strlen(c);
for (i=1;i<=26;i++)
{
a[i].x='a'+i-1;//结构体存储字母。
}
for (i=0;i<l;i++)
{
a[c[i]-'a'+1].y++;
if (a[c[i]-'a'+1].y==1) t++;
}
sort(a+1,a+27,cmp);
for (i=26-t+1;i<=26;i++)
{
if (n>=a[i].y)//若当前字母的出现次数小于等于当前可以删除的字母数量。(一定不要忘了等于!!!)
{
n-=a[i].y;
a[i].y=0;
t--;
b[a[i].x-'a'+1]=1;//布尔数组保存当前字母的已删除状态。
}
else break;
}
printf("%d\n",t)
for (i=0;i<l;i++)//循环遍历输入的字符串,保证输出为输入字符串的子序列。
{
if (!b[c[i]-'a'+1]) printf("%c",c[i]);//若当前字母未被删除,则输出当前字母。
}
return 0;
}