Codeforces 600C Make Palindrome 【贪心 找字典序最小回文串】
#include <iostream> #include <stdio.h> #include <string.h> #include <cstring> using namespace std; const int N = 2e5+5; char s[N]; int num[26]={0}; // int mark[26]={0}; char trans[26]={0}; int main() { scanf("%s",s); int len = strlen(s); int unuse = 0; char mid = '0'; for(int i=0; i<len; i++) num[s[i]-'a']++; for(int i=0; i<26; i++) { if(num[i]%2) trans[++unuse] = 'a'+i; } /**cout << unuse << endl;*/ for(int i=1; i<=unuse/2; i++) { num[trans[i]-'a']++; num[trans[unuse-i+1]-'a']--; } if(len%2) mid = trans[unuse/2+1]; int F=0, B=len-1; // 我们最后是通过记录改变完字母后的每个字母的出现次数来按照字典序重排字符串的 for(int i=0; i<26; i++) { /**cout << num[i] << " ";*/ for(int j=F; j<F+num[i]/2; j++) s[j] = 'a' + i; F += num[i] / 2; for(int j=B; j>B-num[i]/2; j--) s[j] = 'a' + i; B -= num[i] / 2; } if(len%2) s[len/2] = mid; cout << s << endl; return 0; }