1. 程式人生 > 其它 >3207. 【HNOI模擬題】Orthogonal Anagram

3207. 【HNOI模擬題】Orthogonal Anagram

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_i\le 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;
}