校赛——1096Is The Same?(KMP或字符串的最小、大表示法)

1096: Is The Same?

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 26  Solved: 8
[Submit][Status][Web Board]

Description

给出2个字符串S和T,如果可以通过循环移位使得S和T相等,则我们称S和T是同构字符串, 例如S=“abcd”, T=“bcda”,则S和T是同构字符串;而S=“abcd”和T=“bcad”则不是同构字符串。
循环移位是指:在⼀个长度为n的字符串S中,取⼀个任意下标i,把字符串分为两段,分别为 S1S2...Si 和Si+1Si+2...Sn,然后把字符串变为Si+1Si+2...SnS1S2...Si,例如S=“qwerty”,取i=3, 则变 为”rtyqwe”(注意,一个字符串本⾝身也算是它的同构字符串)。 

 

Input

第⼀行包含一个整数T(1 <= T <= 20),代表测试组数。
对于每组数据,包含2个字符串,字符串长度都小于等于105且非空,输入保证字符串只包含小写字⺟。 

 

Output


对于每组数据,如果这两个字符串是同构字符串,则输出Yes,否则输出No。 

 

Sample Input

2
abcd
bcda
abcd
bcad

Sample Output

Yes
No

比赛的时候用的是据说效率差不多的strstr过的,毕竟题目只是要求输出是否匹配而不是查找出现位置。KMP比较长打起来费时间而且清空数组又要打一堆

代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
#define MM(a) memset(a,0,sizeof(a))
const int N=100010;
char a[N],b[N],aa[2*N],bb[2*N];
int nexta[N],nextb[N];
inline void getnext(int ne[],char s[])
{
	int j=0,k=ne[0]=-1;
	int len=strlen(s);
	while (j<len)
	{
		if(k==-1||s[j]==s[k])
		{
			j++;
			k++;
			ne[j]=k;
		}
		else
			k=ne[k];
	}
}
inline bool kmp(int ne[],char s[],char p[])
{
	int i=0,j=0;
	int la=strlen(s),lb=strlen(p);
	while (i<la&&j<lb)
	{
		if(s[i]==p[j]||j==-1)
		{
			i++;
			j++;
		}
		else
			j=ne[j];
	}
	if(j==lb)
		return true;
	else
		return false;
}
int main(void)
{
	int tcase,i,j;
	scanf("%d",&tcase);
	while (tcase--)
	{
		MM(a);
		MM(b);
		MM(aa);
		MM(bb);
		MM(nexta);
		MM(nextb);
		scanf("%s%s",a,b);
		if(strlen(a)!=strlen(b))
		{
			puts("No");
			continue;
		}
		strcat(aa,a);
		strcat(aa,a);
		strcat(bb,b);
		strcat(bb,b);
		getnext(nexta,a);
		getnext(nextb,b);
		if(kmp(nexta,bb,a)||kmp(nextb,aa,b))
			puts("Yes");
		else
			puts("No");
	}
	return 0;
}

最小表示法代码:

 

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
inline string minP(string s)
{
	int i=0,j=1,k=0,l=s.size();
	while (1)
	{
		if(i+k>=l||j+k>=l) 
			break;
		if(s[i+k]==s[j+k])
		{
			k++;
			continue;
		}
		else
		{
			if(s[j+k]>s[i+k]) 
				j+=k+1;
			else 
				i+=k+1;
			k=0;
			if(i==j) 
				j++;
		}
	}
	s=s+s;
	return s.substr(min(i,j),l);
}
int main(void)
{
    ios::sync_with_stdio(false);
    int tcase;
    string a,b;
    cin>>tcase;
    while (tcase--)
    {
        cin>>a>>b;
        a=minP(a);
        b=minP(b);
        if(a==b)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
    return 0;
}

  

你可能感兴趣的:(校赛——1096Is The Same?(KMP或字符串的最小、大表示法))