题解
- 我们可以预处理出每个字母出现的次数l[i]和没有出现的次数r[i]
- 若一个字母出现的次数>没有出现的次数,那么显然这个是没有方案的,因为要满足每一位的字母都不一样,这样的话,就超过n/2个了,显然不能形成
- 现在来想一下如何用预处理出来的数组来求答案
- 考虑贪心的思想,要使字典序最小,那么可以放的最小的字母可以先放
- 那么就枚举放的字母,若l[i]=r[i],也就是说,它占整个字符串的一半,而且我们是按顺序枚举过来的,显然可以放
- 若没有以上的情况,那么我们就找第一个不等于字符串相对位置,而且是出现过的字母放就好了
代码
1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4 int l[26],r[26],n;
5 char s[50010];
6 int main()
7 {
8 scanf("%s",s+1),n=strlen(s+1);
9 for (int i=1;i<=n;i++) for (int j=0;j<26;j++) if (s[i]==j+97) l[j]++; else r[j]++;
10 for (int i=0;i<26;i++) if (l[i]>r[i]) return 0;
11 for (int i=1;i<=n;i++)
12 {
13 int x=26;
14 for (int j=0;j<26;j++) if (s[i]!=(j+97)&&l[j]==r[j]) x=j;
15 if (x==26) for (int j=0;j<26;j++) if (s[i]!=(j+97)&&l[j]) {x=j; break;}
16 printf("%c",x+97),l[x]--;
17 for (int j=0;j<26;j++) if (s[i]!=(j+97)) --r[j];
18 }
19 }