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;
}
posted @ 2022-03-23 20:31  Jason142  阅读(30)  评论(0编辑  收藏  举报