1. 程式人生 > >BZOJ1398Vijos1382尋找主人 Necklace——最小表示法

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

bitset names led line else if while online ring ()

題目描述

技術分享圖片

給定兩個項鏈的表示,判斷他們是否可能是一條項鏈。

輸入

輸入文件只有兩行,每行一個由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]);
	}
}

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