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_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;
} 
原文地址:https://www.cnblogs.com/Livingston/p/15369572.html