ACdream之kmp

D - 娜娜梦游仙境系列——村民的怪癖

Time Limit:  2000/1000MS (Java/Others)     Memory Limit:  128000/64000KB (Java/Others)
Problem Description

娜娜费劲九牛二虎之力终于把糖果吃完了(说好的吃不完呢?骗人,口亨~),于是,缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷,娜娜甚异之。复前行,欲穷其林。林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田美池桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。(摘自《桃花源记》)

 

娜娜与村民交流了好久才发现这里的人们给孩子的命名方式很奇怪,首先村民们的名字都是用专门的符号来记录,正好是26个符号,于是娜娜就把它们替换成‘a’~‘z’,然后首先把爸爸的名字作为孩子的姓,妈妈的名字作为孩子的名。这时候肯定有人会问,不是独生子女怎么办?很简单~取拼接好的名字的前缀与后缀相同的部分从短到长依次作为孩子的姓名,啥,不够?那就不许你再生孩子!

 

不过由于桃花村民与世隔绝太久了,以致于他们总是无法正确判断一对夫妻最多能生多少个孩子,于是就把这个任务交给你了。

 

P.S. 若用S[1,n]表示一个长度为n的字符串,那么S[1,i](1<=i<=n)表示S的一个前缀,S[j,n](1<=j<=n)表示S的一个后缀。具体看样例解释

Input

多组数据,首先是一个正整数t(t<=20),表示数据的组数

对于每一组数据,包含两个只由'a'~'z'组成的不含空格的字符串S1,S2,分别代表丈夫的姓名以及妻子的姓名。(1<=|S1|,|S2|<=100000)

 

Output
对于每组数据,输出一个整数,表示这对夫妻最多可以生育多少个孩子。
Sample Input
2
ababc ababa
aaaaa aaa
Sample Output
3
8
Hint

对于样例1,把丈夫和妻子的姓名拼接在一起是ababcababa,可以作为孩子的姓名的是a、aba、ababcababa,故最多生育3个孩子

对于样例2,把丈夫和妻子的姓名拼接在一起是aaaaaaaa,可以作为孩子的姓名的是a、aa、aaa、aaaa、aaaaa、aaaaaa、aaaaaaa、aaaaaaaa,故最多生育8个孩子

这道题虽然是一道kmp的题目,但是暴力却能过,暴力代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
const int N=1e5+10;
int t;
char s1[2*N],s2[2*N];
int main()
{
    cin>>t;
    while(t--)
    {
        scanf("%s%s",s1,s2);
        strcat(s1,s2);
        strcpy(s2,s1);
        int len=strlen(s1);
        int ans=0;
        for(int i=0;i<len;i++)
        {
            char temp=s1[i];
            s1[i]='\0';
            if(!strcmp(s1,s2+(len-i)))
                ans++;
            s1[i]=temp;
        }
        cout<<ans<<endl;
    }
    return 0;
}
kmp代码:kmp真的是不好理解,留着以后慢慢理解吧:
// File Name: d.cpp
// Author: darkdream
// Created Time: 2015年04月12日 星期日 19时40分52秒

#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<sstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>
#define LL long long

using namespace std;
int n ; 
int t; 
char str[300000];
int len ; 
int next[300000];
void get_next()
{
    next[0] = -1; 
    int k = -1; 
    int j =0 ; 
    while(j < len )
    {
      if(k == -1 || str[j] == str[k])
      {
         ++ k ; 
         ++ j ;
         next[j] = k ; 
      }else{
         k = next[k];
      }
    }
}
int find(int x)
{
   if(x == 0)
       return 0; 
   return 1+find(next[x]);
}
int main(){
    scanf("%d",&t);
    while(t--)
    {
      scanf("%s",str);
      len = strlen(str);
      scanf("%s",&str[len]);
      len = strlen(str);
      get_next();
      printf("%d\n",find(len));
    }
return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值