HDU 2203 亲和串


亲和串
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Christmas is coming! But on Christmas Eve, Li Laoshi still has one more class to take. His teacher asked him to find all the “Christmas Strings” within many pairs of strings, only after he find all the Christmas Strings can he go back his dorm and play computer games.

“Christmas Strings” is defined as follows: given two strings S1 and S2, after circulating shifts of S1, if S2 is a substring the shifted string, then we say S2 is a “Christmas Strings” of S1.

Li Laoshi is very eager to finish the class early, can you help him to find a way to solve the problem quickly?

Input

There are multiple test cases. The first line of every test case contains string S1, and the second line contains string S2. The length of S1and S2 are both shorter than 100000.

Output

Print one line for each test case. If S2 is a “Christmas Strings” of S1, print ”yes”, else print “no”.

Sample Input

 AABCD
CDAA
ASD
ASDF

Sample Output

yes
no 

Hint

In the first test case: we can get the circulating shifted string as: BCDAA or CDAAB, because CDAA is a sub string of the shifted string, we print “yes” for answer.



求亲和串

该题请求一个串轮回后是否包含别的一个串,其实只要将母串反复一次再进行KMP匹配就行了,因为在反复母串的过程中,其实据已经将轮回后的所有可能都列举出来了,比如串 "ABCD" 反复后为  "ABCDABCD" 在这个串中 "BCDA" , "CDAB" 以及 "DABC" 都接踵呈现了。故ABCD=ABCDABCD,在进行KMP匹配就行

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;

int nex[1000005];
void pre(string b){
    nex[0]=-1;
    int i=0,j=-1,len=b.size();
    while(i<len){
        if(j==-1||b[i]==b[j]){
            i++;j++;
            nex[i]=j;
        }else
            j=nex[j];
    }
}
bool kmp(string str1,string str2){
    if(str1.size()<str2.size()) return 0;
    pre(str2);
    int i=0,j=0,len1=str1.size(),len2=str2.size();
    while(i<len1&&j<len2){
        if(j==-1||str2[j]==str1[i]){
            i++;
            j++;
        }else
            j=nex[j];
        if(j==len2){
            return 1;
        }
    }
    return 0;
}
int main()
{
    std::cout.sync_with_stdio(false);
    string str1,str2;
    while(cin>>str1>>str2){
        if(kmp(str1+str1,str2))
            cout<<"yes"<<endl;
        else
            cout<<"no"<<endl;
    }
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值