其他分享
首页 > 其他分享> > jzoj 3207.【HNOI模拟题】Orthogonal Anagram 霍尔定理+贪心

jzoj 3207.【HNOI模拟题】Orthogonal Anagram 霍尔定理+贪心

作者:互联网

Description

一个字符串的变形词是一个字符串,它含有恰好完全一样的字母,可能以不同的顺序出现。例如,\porter",\report"和\eoprrt"都是\porter"的变形词。而\potter"不是它的变形词,因为\t"和\r"出现的次数不同。

字符串S和T是正交的,当且仅当它们长度相同,而且每个对应位都不同。例如,\card"和\dear"是正交的,而\perk"和\card"不是正交的,因为它们的第3个字母相同。

给出一个字符串S,求S的字典序最小的正交变形词。如果这样的字符串不存在,就让答案是空串。

Input
仅一行,一个字符串S。

Output
仅一行,表示答案。

Sample Input
abba

Sample Output
baab

Data Constraint
有10%数据,字符串长度不超过10。
另有10%数据,恰有2种不同的字母。
另有20%数据,只有不超过5种不同的字母。
对于80%数据,字符串长度不超过50。
对于100%数据,字符串长度不超过50000,所有字符都是小写拉丁字母。

分析:
我们把第一个串的字母对第二个串字母进行匹配,显然合法匹配就是两两不相同。
匹配建图就是每个字母向它的不同字母连边。
显然根据这个二分图的特殊性质,根据霍尔定理,左边如果选了两个不同字母,对应右边一定是全集,一定符合。所以左边选尽量多的相同字母,如果都能满足就存在完全匹配。

suml[i]suml[i]suml[i]表示字母iii在左边的个数,sumr[i]sumr[i]sumr[i]表示字母iii在右边的个数,ddd为带匹配的总字母数。
如果存在完全匹配,那么i[a,z]suml[i]&lt;=dsumr[i]\forall i\in[a,z] suml[i]&lt;=d-sumr[i]∀i∈[a,z]suml[i]<=d−sumr[i]。
对于每一位贪心求,暴力枚举每一个字母,判断选了之后是否存在完全匹配即可。
复杂度是O(262len)O(26^2len)O(262len)。

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>

const int maxn=50007;

using namespace std;

int n,l;
int numl[30],numr[30];
char s[maxn];

int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);	
	for (int i=1;i<=n;i++)
	{
		numl[s[i]-'a']++;
		numr[s[i]-'a']++;
	}
	int flag=0;
	for (int i=0;i<26;i++)
	{
		if (numl[i]>n-numr[i])
		{
			flag=1;
			break;
		}
	}
	if (flag==1) return 0;
	l=n;
	for (int i=1;i<=n;i++)
	{
		numl[s[i]-'a']--;
		l--;
		for (int j=0;j<26;j++)
		{
			if ((s[i]-'a'==j) || (!numr[j])) continue;
			flag=0;
			numr[j]--;
			for (int k=0;k<26;k++)
			{
				if (numl[k]>l-numr[k])
				{
					flag=1;
					break;
				}
			}
			if (!flag) 
			{
				printf("%c",'a'+j);
				break;
			}
			else numr[j]++;
		}
	}
}

标签:3207,匹配,Orthogonal,int,字母,sumr,模拟题,suml,字符串
来源: https://blog.csdn.net/liangzihao1/article/details/86682055