1. 程式人生 > >hdu 2203 kmp 親和串

hdu 2203 kmp 親和串

親和串

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18150    Accepted Submission(s): 8017

Problem Description

人隨著歲數的增長是越大越聰明還是越大越笨,這是一個值得全世界科學家思考的問題,同樣的問題Eddy也一直在思考,因為他在很小的時候就知道親和串如何判斷了,但是發現,現在長大了卻不知道怎麼去判斷親和串了,於是他只好又再一次來請教聰明且樂於助人的你來解決這個問題。 親和串的定義是這樣的:給定兩個字串s1和s2,如果能通過s1迴圈移位,使s2包含在s1中,那麼我們就說s2 是s1的親和串。

Input

本題有多組測試資料,每組資料的第一行包含輸入字串s1,第二行包含輸入字串s2,s1與s2的長度均小於100000。

Output

如果s2是s1的親和串,則輸出"yes",反之,輸出"no"。每組測試的輸出佔一行。

Sample Input

AABCD CDAA ASD ASDF

Sample Output

yes no

Author

Eddy

Recommend

lcy   |   We have carefully selected several similar problems for you:  3336 2201 3068 2202 2200 

傳送門

題解

1 題目要求的是給定字串s1 和 s2,問s1能否通過移位得到使得s2包含在s1裡面。 2 很顯然的kmp的模板題,只須在s1後面在添上一個s1即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 0x3f3f3f3f
using namespace std;
string s1,s2;
int nexxt[100010];
void getnext()
{
	int i=0,j=-1;
	nexxt[0]=-1;
	while(i<s2.size())
	{
		if(j==-1||s2[i]==s2[j])
		{
			nexxt[++i]=++j;
		}
		else
		j=nexxt[j];
	}
}
int find()
{
	getnext();
	int i=0,j=0;
	while(i<s1.size())
	{
		if(j==-1||s1[i]==s2[j])
		{
			i++,j++;
		}
		if(j==s2.size())
			return 1;
		if(s1[i]!=s2[j])
		j=nexxt[j];		
	}
	return 0;
}
int main()
{
	while(cin>>s1>>s2)
	{
		s1=s1+s1;		
		if(find())
		{
			cout<<"yes"<<endl;
		}
		else
		cout<<"no"<<endl;
	}
	return 0;
}