csu 1598(KMP)

1598: 最长公共前缀

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 109  Solved: 92
[Submit][Status][Web Board]

Description

给定两个字符串s和t,现有一个扫描器,从s的最左边开始向右扫描,每次扫描到一个t就把这一段删除,输出能发现t的个数。

Input

第一行包含一个整数T(T<=50),表示数据组数。
每组数据第一行包含一个字符串s,第二行一个字符串t,字符串长度不超过1000000。

Output

对于每组数据,输出答案。

Sample Input

2
ababab
ab
ababab
ba

Sample Output

3
2

HINT

Source

国防科学技术大学第十八届银河之光文化节ACM程序设计竞赛初赛

放一个KMP算法模板吧。。还没怎么做过KMP的题.

#include <iostream>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;

const int N = 1000002;
int Next[N];
char S[N], T[N];
int slen, tlen;

void getNext()
{
    int j, k;
    j = 0; k = -1; Next[0] = -1;
    while(j < tlen)
        if(k == -1 || T[j] == T[k])
            Next[++j] = ++k;
        else
            k = Next[k];

}
/*
返回模式串T在主串S中首次出现的位置
返回的位置是从0开始的。
*/
int KMP_Index()
{
    int i = 0, j = 0;
    getNext();

    while(i < slen && j < tlen)
    {
        if(j == -1 || S[i] == T[j])
        {
            i++; j++;
        }
        else
            j = Next[j];
    }
    if(j == tlen)
        return i - tlen;
    else
        return -1;
}
/*
返回模式串在主串S中出现的次数
*/
int KMP_Count()
{
    int ans = 0;
    int i, j = 0;

    if(slen == 1 && tlen == 1)
    {
        if(S[0] == T[0])
            return 1;
        else
            return 0;
    }
    getNext();
    for(i = 0; i < slen; i++)
    {
        while(j > 0 && S[i] != T[j])
            j = Next[j];
        if(S[i] == T[j])
            j++;
        if(j == tlen)
        {
            ans++;
            j = Next[j];
        }
    }
    return ans;
}
int main()
{

    int tcase;
    scanf("%d",&tcase);
    while(tcase--)
    {
        scanf("%s%s",S,T);
        slen = strlen(S);
        tlen = strlen(T);
        printf("%d\n",KMP_Count());
    }
    return 0;
}
时间: 2024-10-03 03:19:45

csu 1598(KMP)的相关文章

CSU 1598 最长公共前缀 (简单KMP或者暴力)

Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 226     Solved: 189 Description 给定两个字符串s和t,现有一个扫描器,从s的最左边开始向右扫描,每次扫描到一个t就把这一段删除,输出能发现t的个数. Input 第一行包含一个整数T(T<=50),表示数据组数. 每组数据第一行包含一个字符串s,第二行一个字符串t,字符串长度不超过1000000.

CSU 1620: A Cure for the Common Code (区间DP KMP预处理)

链接 : http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1620 题意 : 给一个字符串 问怎么压缩字符串使得最终个数最小 具体怎么压缩请参照图示 很好明白. 题目就是需要找到 对于每个后缀 看成一个新字符串 找出它的前缀的最小循环节. 过程和大白书 P213页 是一样的,只需要对每个后缀跑一遍KMP求出周期. 剩下的过程就是区间DP了. dp[i][j] = min ( dp[i][k], dp[k+1][j] ); 如果i - j这一段存在

CSU 1620: A Cure for the Common Code(KMP+区间DP)

Description Input Output Sample Input abcbcbcbca abbbcdcdcdabbbcdcdcd 0 Sample Output Case 1: 7 Case 2: 11 HINT 题意:给一个小写子母的串,相邻相同的子串可以合在一起,问这个串合并后最短可得多长. 解题:KMP & 区间DP #include<stdio.h> #include<string.h> const int N = 505; int next1[N]; c

【KMP】【最小表示法】NCPC 2014 H clock pictures

题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1794 题目大意: 两个无刻度的钟面,每个上面有N根针(N<=200000),每个针都是相同的,分别指向Ai,Bi(360°被分成360000小份),问能否将其中一个旋转和另一个重合. 题目思路: [KMP][最小表示法] 循环同构问题.可以写KMP,我懒得写KMP了就写了循环同构的最小表示法. 首先将Ai排序,然后求差(记得取模360000,WA了一次),接下来复制一遍开始匹配. A

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

hiho 1015 KMP算法 &amp;&amp; CF 625 B. War of the Corporations

#1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一只河蟹,于是河蟹就向小Hi和小Ho提出了那个经典的问题:“小Hi和小Ho,你们能不能够判断一段文字(原串)里面是不是存在那么一些……特殊……的文字(模式串)?” 小Hi和小Ho仔细思考了一下,觉得只能想到很简单的做法,但是又觉得既然河蟹先生这么说了,就

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>

hdu2328 Corporate Identity 扩展KMP

Beside other services, ACM helps companies to clearly state their "corporate identity", which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently asked ACM for

CSU 1111: 三家人【有趣的思维题】

1111: 三家人 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 2241  Solved: 874 [Submit][Status][Web Board] Description 有三户人家共拥有一座花园,每户人家的太太均需帮忙整理花园.A 太太工作了5 天,B 太太则工作了4 天,才将花园整理完毕.C 太太因为正身怀六甲无法加入她们的行列,便出了90元.请问这笔钱如何分给A.B 二位太太较为恰当?A 应得多少元?90/(5+4)*5=$50