Description
一个字符串的变形词是一个字符串,它含有恰好完全一样的字母,可能以不同的顺序出现。例如,porter,report和eoprrt都是 porter 的变形词。而 potter 不是它的变形词,因为 t 和 r 出现的次数不同。
字符串S和T是正交的,当且仅当它们长度相同,而且每个对应位都不同。例如,card 和 dear 是正交的,而 perk 和 card 不是正交的,因为它们的第3个字母相同。
给出一个字符串S,求S的字典序最小的正交变形词。如果这样的字符串不存在,就让答案是空串。
Solution
对于每个字母,维护 (x_i) 和 (y_i) 表示字母 (i) 要用的次数和还有多少个位置没有填。
对于每个位置,贪心填字母,合法的情况是对于每个字母都满足 (x_i+y_ile len),(len) 表示剩下的长度。
Code
#include<cstdio>
#include<cstring>
#define N 50005
using namespace std;
int n,numl[N],numr[N];
bool flag;
char s[N];
int main()
{
scanf("%s",s+1);
n=strlen(s+1);
for (int i=1;i<=n;++i)
{
numl[s[i]-'a'+1]++;
numr[s[i]-'a'+1]++;
}
for (int i=1;i<=26;++i)
if (numl[i]+numr[i]>n)
return 0;
for (int i=1;i<=n;++i)
{
numl[s[i]-'a'+1]--;
for (int j=1;j<=26;++j)
{
if ((!numr[j])||s[i]-'a'+1==j) continue;
numr[j]--;
flag=true;
for (int k=1;k<=26;++k)
if (numl[k]+numr[k]>n-i)
{
flag=false;
break;
}
if (flag)
{
printf("%c",j-1+'a');
break;
}
else numr[j]++;
}
}
return 0;
}