2833. Homework

Once when Gerald studied in the first year at school, his teacher gave the class the following homework. She offered the students a string consisting of n small Latin letters; the task was to learn the way the letters that the string contains are written. However, as Gerald is too lazy, he has no desire whatsoever to learn those letters. That’s why he decided to lose some part of the string (not necessarily a connected part). The lost part can consist of any number of segments of any length, at any distance from each other. However, Gerald knows that if he loses more than k characters, it will be very suspicious.

Find the least number of distinct characters that can remain in the string after no more than k characters are deleted. You also have to find any possible way to delete the characters.

Input
The first input data line contains a string whose length is equal to n (1≤n≤105). The string consists of lowercase Latin letters. The second line contains the number k (0≤k≤105).

Output
Print on the first line the only number m − the least possible number of different characters that could remain in the given string after it loses no more than k characters.

Print on the second line the string that Gerald can get after some characters are lost. The string should have exactly m distinct characters. The final string should be the subsequence of the initial string. If Gerald can get several different strings with exactly m distinct characters, print any of them.

Examples
Input

aaaaa
4

Output

1
aaaaa

Input

abacaba
4

Output

1
aaaa

Input

abcdefgh
10

Output

0

Note
In the first sample the string consists of five identical letters but you are only allowed to delete 4 of them so that there was at least one letter left. Thus, the right answer is 1 and any string consisting of characters “a” from 1 to 5 in length.

In the second sample you are allowed to delete 4 characters. You cannot delete all the characters, because the string has length equal to 7. However, you can delete all characters apart from “a” (as they are no more than four), which will result in the “aaaa” string.

In the third sample you are given a line whose length is equal to 8, and k=10, so that the whole line can be deleted. The correct answer is 0 and an empty string.

这道题目的大致意思是:尽可能多的删除所给字符串中的字母种类

#include <stdio.h>
#include <string.h>
#define MaxSize 100002

//该函数获取数组中的非零最小值,以及对应的字母
// min 为所需最小值
// numOfLetter 数组中存储了输入字符串中每种类型字母的个数
char getMin(int *min, int *numOfLetter)
{
	int i;
	int j = 0;									// j 用来标记数量最少字母所在的位置
	for (i = 0; i < 26; i++) {			//求最小值 min 以及 j
		if (numOfLetter[i] != 0 && numOfLetter[i] < *min) {
			*min = numOfLetter[i];
			j = i;
		}
	}
	numOfLetter[j] = 0;					//将数组中对应的数量清零,避免重复计算
	return j + 'a';							//返回数量最少的字母
}

int deleteLetter(char *s, char c, int n)       //从字符串 s 中将所有的 c 删去 
{
	int i;
	int num = 0;								//已删除的字符数
	for (i = 0; i < n; i++)
	{
		if (s[i] == c) num++;
		else s[i - num] = s[i];
	}
	return n - num;                     //删除字符后,字符串的长度
}

int main()
{
	char s[MaxSize];
	int k;
	scanf("%s", s);
	scanf("%d", &k);

	int numOfLetter[26] = { 0 };
	
	//当 k 不小于 s 的长度时
	if (strlen(s) <= k)
	{
		printf("0\n");
		printf(" ");
		return 0;
	}

	//当 k 小于 s 的长度时
	int i;
	char minNumLetter;                  //数量最少的字母

	int deleteNum = 0;                  //已删除字母的个数

	for (i = 0; i < strlen(s); i++)      //统计每个种类的字母的个数
		numOfLetter[s[i] - 'a']++;

	int length = strlen(s);				//记录字符串的有效长度

	while (k > deleteNum)
	{
		int min = MaxSize;
		int *minNum;                     //最少的数量
		minNum = &min;

		//获取数量最少的字符 minNumletter
		//获取数量 minNum
		minNumLetter = getMin(minNum, numOfLetter);
		deleteNum += *minNum;

		//将获取到的字母从字符串中删除
		if (k >= deleteNum)
			length = deleteLetter(s, minNumLetter, length);
	}

	for (i = 0; i < length; i++) {				//统计处理后的字符串中每个种类的字母的个数
		numOfLetter[s[i] - 'a']++;
	}

	int m = 0;
	for (i = 0; i < 26; i++) {
		if (numOfLetter[i] > 0) m++;
	}
	printf("%d\n", m);							//输出字符串中剩余字符的种类

	for (i = 0; i < length; i++) {				//输出处理后的字符串
		printf("%c", s[i]);
	}

	return 0;
}
展开阅读全文
©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值