BZOJ1398Vijos1382寻找主人 Necklace——最小表示法

题目描述

给定两个项链的表示,判断他们是否可能是一条项链。

输入

输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的)。

输出

如果两条项链不可能同构,那么输出’No’,否则的话,第一行输出一个’Yes’
第二行输出该项链的字典序最小的表示。 设L = 项链长度,L <= 1000000。

样例输入

2234342423
2423223434

样例输出

Yes
2234342423
 
判断两个字符串是否循环同构只要将两个字符串的最小循环同构串找到判断是否相同即可,分别用最小表示法求一下即可。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
char s[2000010];
char t[2000010];
int find(char *s,int n)
{
	int l=1;
	int r=2;
	while(l<=n&&r<=n)
	{
		if(s[l]<s[r])
		{
			r++;
		}
		else if(s[l]>s[r])
		{
			l=r++;
		}
		else
		{
			int k;
			for(k=1;k<n;k++)
			{
				if(s[l+k]>s[r+k])
				{
					l=r++;
					break;
				}
				else if(s[l+k]<s[r+k])
				{
					r=r+k+1;
					break;
				}
			}
		}
	}
	return l;
}
int main()
{
	scanf("%s%s",s+1,t+1);
	int len=strlen(s+1);
	for(int i=len+1;i<=2*len;i++)
	{
		s[i]=s[i-len];
		t[i]=t[i-len];
	}
	n=find(s,len);
	m=find(t,len);
	for(int i=n,j=m;len--;i++,j++)
	{
		if(s[i]!=t[j])
		{
			printf("No");
			return 0;
		}
	}
	len=strlen(s+1)/2;
	printf("Yes\n");
	for(int i=n;i-n+1<=len;i++)
	{
		printf("%c",s[i]);
	}
}
posted @ 2019-02-07 16:08  The_Virtuoso  阅读(193)  评论(0编辑  收藏  举报