CF1063A

首先看题目:
一个非空字符串叫做回文串。如果它从左到右,从右到左读相同,那么它就是回文串。 例如,“ABCBA”,“A”和“ABBA”都是回文串,而“ABAB”和“XY”则不是。
如果可以通过从字符串的开头和结尾删除一些(可能为零)字符来从该字符串获得新字符串, 则新字符串叫做另一个字符串的子字符串。 例如,“ABC”、“AB”和“C”是字符串“ABC”的子串,而“AC”和“D”不是。
我们把字符串的“回文计数”定义为回文的子串个数。 例如,字符串“aaa”的回文计数是6,因为它的所有子字符串都是回文, 而字符串“abc”的回文计数是3,因为只有长度为1的子字符串是回文。
给你一个字符串S。你可以任意地重新排列它的字符,求它的回文计数最大值。
输入格式:
第一行包含整数n(1≤n≤100000)表示字符串s的长度。
第二行包含字符串S,它由n个小写字母组成。
输出格式:
输出字符串t,(它是字符串s的一种排列) 此外,t应该具有最大回文计数的可能值。
如果有多个这样的字符串,输出它们中的任何一个。

首先考虑只有两种元素的字符串,假设有多个a和一个b那么无论怎么放置这个b,只有b在这串a的最前面或者最后面时,这串字符串的回文计数最大。
接下来考虑有两个b的情况,发现只有两个b放在一起时,回文计数最大。
那么考虑三种元素的情况,发现如果三种元素个数相同,那么只需要把同一元素放在一起即可。如果个数不同,则按照个数多少排序即可。例如abbccc或者cccbba。这两个字符串回文计数都是最大的。
那么推广到多个,只需要按照字符出现次数排序然后依次输出即可。

#include <iostream>
#include <algorithm>

using namespace std;

//#define DEBUG

int main()
{
	static char a[100001];
	int n,b[26]={0};//统计字符出现次数
	int *ps[26];//保存指向b中每个元素的指针 
	cin >> n >> a;
	for(int i=0;i<26;i++){
		b[i]=count(a,a+n,i+'a');//统计并存入b 
		ps[i]=b+i;//保存指针 
	}
	sort(ps,ps+25,[](int *p1,int *p2){return *p1>*p2;});
	//排序,这里对指针排序而没有改变原来数组的元素位置 
	#ifdef DEBUG
	for(int i=0;i<26;i++){
		cout << *ps[i] << endl;
	}
	#endif
	for(int i=0;i<26;i++){
		for(int j=0;j<*ps[i];j++){
			cout << char(ps[i]-b+'a');
		}
	}
	return 0;
}

这里调用了algorithm库下的sort函数,因为排序时不想打乱原来数组的顺序,所以用了对指针进行了排序。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值