hdu 2594 Simpsons’ Hidden Talents

点击打开链接hdu 2594

思路:kmp+next数组的应用

分析:
1 题目要求的是给定两个字符串s1 , s2找到s1的最长前缀等于s2的后缀
2 很明显就是next数组的应用,我们知道next[j] = len,表示的前j个字符里面前缀和后缀的最长匹配长度为len。那么我们只要合并两个字符串然后求next数组即可。
3 注意以下的数据
abcabcabcabc
abcabcabcabcabc
输出 12
abcabc
abc
输出 3

我们知道如果合并了s1和s2的话,那么求出来的最长的长度是24 和 6显然是不行的,因为我们忽略了一个地方就是求出的最长的前缀的长度是不能超过
s1和s2的长度的,所以求出最长前缀长度后应该进行讨论。

代码:

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

#define MAXN 100010

char s1[MAXN/2];
char s2[MAXN/2];
char pattern[MAXN];
int next[MAXN];

void getNext(){
    int n = strlen(s1);
    int m = strlen(s2);
    next[0] = next[1] = 0;
    for(int i = 1 ; i < n+m ; i++){
       int j = next[i];
       while(j && pattern[i] != pattern[j])
           j = next[j];
       next[i+1] = pattern[i] == pattern[j] ? j+1 : 0;
    }
    if(!next[n+m])
      printf("0\n");
    else{
      int tmp = next[m+n];
      s1[tmp] = '\0';
      if(n > m){/*如果第一串大于第二串*/
        if(tmp > m)/*如果tmp>第二串长度直接输出第二串*/
          printf("%s %d\n" , s2 , m);
        else
          printf("%s %d\n" , s1 , tmp);
      }
      else{/*如果第一串小于第二串*/
        if(tmp > n)/*如果tmp>第一串的长度直接输出第一串*/
          printf("%s %d\n" , s1 , n);
        else
          printf("%s %d\n" , s1 , tmp);
      }
    }
}

int main(){
   while(scanf("%s" , s1) != EOF){
       scanf("%s" , s2);
       memcpy(pattern , s1 , sizeof(s1));
       strcat(pattern , s2);
       getNext();
   }
   return 0;
}
时间: 2024-08-31 14:52:48

hdu 2594 Simpsons’ Hidden Talents的相关文章

算法题:HDU 2594 Simpsons’ Hidden Talents(KMP)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=2594 题目大意: 给两个字符串s1和s2, 求出是s1的前缀并且是s2的后缀的最长的字符串. 分析与总结: 真正理解好KMP算法,这题就是水题. 首先求出s1的失配函数,然后在s2中 寻找s1字符串. 在寻找字符串过程中,会有一个状态值j,这个值表示的是当前在s2中已经匹配 了多少个s1的字符. 所以,全部匹配完后,最后j的值就是以s2的最后一个字符结尾,和s1的前缀相匹 配的最长字符串.也就是所求的

KMP专题【完结】

第一题 hdu 1711 Number Sequence 点击打开hdu 1711 思路: 1 kmp是用来匹配字符串,只能够匹配单一的字符串 2 kmp的算法的过程:   1:假设文本串的长度为n,模式串的长度为m:   2:先例用O(m)的时间去预处理next数组,next数组的意思指的是当前的字符串匹配失败后要转到的下一个状态:   3:利用o(n)的时间去完成匹配: 3 时间复杂度为o(n+m)即o(n): 点击查看代码 第二题 hdu 1686 oulipo 点击打开hdu 1686

HDU 1271 Arbitrage

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1217 题目: Arbitrage Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2594    Accepted Submission(s): 1167 Problem Description Arbitrage is the use of

hdu 1527

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1527 hint:威佐夫博弈 基本类似于模板 #include <iostream> #include <cmath> #include <cstdio> using namespace std; const double q = (1 + sqrt(5.0)) / 2.0; // 黄金分割数 int Wythoff(int a, int b) { if (a > b)

hdu 2551 竹青遍野

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2551 hint:就是读懂题就行了 #include <iostream> #include <cstdio> using namespace std; typedef long long LL; LL data[1005]; int main() { data[0]=0; for(int i=1; i<1005; i++) data[i]+=data[i-1]+i*i*i; LL

hdu 2054 A == B?

http://acm.hdu.edu.cn/showproblem.php?pid=2054 此题巨坑,刚开始我以为是简单的水题,就用strcmp过, but错了,后来经过我苦思冥想,结果还有几组数据 0.0 和 0,1.000和1.0 , 但是我不太确定前面的0是不是有作用我还是写了,但是有人过的时候,前面的0没考虑比如: 002和2可能是相等的,也可能是不想等的所以不用判断,只能说明hdu数据不是很强啊,嘿嘿 代码如下: #include <iostream> #include <c

hdu 4430 Yukari&#039;s Birthday

点击打开链接hdu 4430 思路:枚举r+二分k 分析: 1 题目要求的是找到一组最小的r*k,如果r*k相同那么就找r最小的. 2 很明显k>=2,根据n <= 10^12,那么可以知道r的最大值r<50,所以只要枚举枚举r的值,然后二分k的大小找到所有的解,存入一个结构体里面,然后在对结构体排序,那么这样就可以得到最后的ans 3 注意题目说了中心点最多一个蜡烛,所以写二分的时候应该注意判断的条件: 4 还有可能计算得到结果超了long long直接变成负数所以应该对或则个进行判断

hdu 1238 Substrings

点击打开链接hdu 1238 思路:kmp+暴力枚举子串 分析: 1 题目要求找到一个子串x,满足x或x的逆串是输入的n个字符串的子串,求最大的x,输出x的长度 2 题目的n最大100,每一个字符串的最大长度为100,那么暴力枚举子串就是o(n^2)才10000肯定是不会超时的,但是由于这里涉及到了逆串的问题,所以我们应该还要求出n个子串的逆串,然后在求最大的x. 代码: #include<iostream> #include<algorithm> #include<cstd

hdu 1857 Word Puzzle

点击打开链接hdu 1857 思路:字典树 分析: 1 题目要求的是给定的单词第一个字母在这个矩形里面的最小的坐标 2 矩形的最大500*500,单词的来源有三个方向,并且单词的起点和终点在矩形之内都是可能的.所以的如果利用枚举矩形之内的单词,那么肯定是超内存的 3 所以我们必须考虑另一种的方法就是对单词进行建字典树,那么我们只要去枚举单词的可能的起点,然后进行查找相应的单词是不是在树上,如果是的话就标记一下当前的坐标. 4 注意由于单词的来源有三个方向,但是因为要求的如果下相同的情况下要求坐标