CG Online Judge——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.

官方翻译

有一次,杰拉尔德在学校学习的第一年,他的老师给全班布置了如下的家庭作业。她给学生们一根由n个拉丁字母组成的字符串;任务是学习字符串中字母的书写方式。然而,由于杰拉尔德太懒了,他根本不想学那些字母。这就是为什么他决定失去部分弦(不一定是连接的部分)。丢失的部分可以由任意长度、任意距离的任意段组成。然而,Gerald知道如果他失去了超过k个字符,那就非常可疑了。

查找删除不超过k个字符后可以保留在字符串中的不同字符的最小数目。您还必须找到任何可能的方法来删除字符。

本人翻译

给你一个字符串,全是小写字母的那种,再给你一个最多可以删除的个数k,也就是说你最多只能删除k个字符,让你求,删除几个字符能使剩下字符种类最少,并且数一数剩下有几种字母。你删除的字符数量不能大于题目给你的k

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.

翻译

请注意

在第一个示例中,字符串由5个相同的字母组成,但是您只能删除其中的4个字母,这样至少还剩下一个字母。因此,正确的答案是1和任何由长度从1到5的字符“a”组成的字符串。

在第二个示例中,您可以删除4个字符。不能删除所有字符,因为字符串的长度等于7。但是,您可以删除除“a”之外的所有字符(因为它们不超过4个),这将产生“aaaa”字符串。

在第三个示例中,给出了一条长度为8的直线,k=10,因此可以删除整条直线。正确答案是0和一个空字符串。

————————————————————————————————————————————
以上是题目
在这里插入图片描述
以下是解答
————————————————————————————————————————————

#include<iostream>
#include<string>
char transformToChar(int a);//整数转换为字母,本题没用到
int transformToInt(char a);//字母转换为整数
int count(int *a);//数字符串中不同字符个数
int min(int *a);//找出字符串中出现次数最少的数
using namespace std;
int main() {
	string str;
	unsigned int k;
	int array[27] = { 0 };
	cin >> str;//输入字符串

	for (unsigned int i = 0; i < str.length(); i++) {//用一个循环记录字符串中字符出现次数
		array[transformToInt(str[i])]++;
	}
	cin >> k;//输入最多能删除字符串的个数
	int copyk=k;//定义一个k的副本,如果不定义copyk而直接用k来进行运算会有警告提示信息,但不会出错。因为k是没有正负号的整数。
	if (k > str.length()) {
		cout << 0;//如果最多能删除的个数大于字符串长度,那就全删了
		goto a;//跳到代码结尾
	} else {//当可以删除的字符数小于字符串长度
		while (copyk >= array[min(array)]) {//当可以删除的字符数目大于字符串中出现次数最少的字符个数
			if (copyk > 0) {//如果可以删的字符数目大于0
				if(count(array)==1)goto b;//如果字符串中只剩下一种字符,那也没必要删了,肯定删不完。直接跳转到输出结果那行
				array[min(array)]--;//从字符串中出现次数最少的那个字符开始删起
				copyk--;//可以删除的字符数-1
			}
		}
			goto b;//当可以删除的字符数目小于字符串中出现次数最少的字符个数,那就不用删了,反正也删不干净,直接输出

	}
	b: cout << count(array) << endl;

	for (unsigned int i = 0; i < str.length(); i++) {//按原字符串排列顺序输出字符
		if (array[transformToInt(str[i])] > 0) {//如果字符串中字符出现次数>0
			cout << str[i];
			array[transformToInt(str[i])]--;
		}
	}

	a: return 0;
}

int transformToInt(char a) {//字符转整数,用于开头记录字符出现个数

	int asc = a;
	return asc - 96;
}

char transformToChar(int a) {//整数转字符,代码中没用到哈哈哈
	char asc = a;
	return asc + 96;
}

int count(int *a) {//数字符串中不同字符个数
	int count = 0;
	for (int i = 0; i < 27; i++) {
		if (*a > 0) {
			count++;
		}
		a++;
	}
	return count;
}
int min(int *a) {//找出字符串中出现次数最少的字符的那个位置
	int min = 99;
	int flag = 0;
	for (int i = 0; i < 27; i++) {
		if ((min > *a) && (*a > 0)) {
			min = *a;
			flag = i;
		}
		a++;
	}
	return flag;
}

以上是我的解题思路,欢迎交流学习。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamerForLife

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值