UVA 1328 - Period KMP

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36131

题意:给出一个长度为n的字符串,要求找到一些i,满足说从1~i为多个个的重复子串构成,并输出子串的个数。

题解:对kmp中预处理的数组的理解

//作者:1085422276
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include<bits/stdc++.h>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
const int inf = 10000000;
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)
    {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘)
    {
        x=x*10+ch-‘0‘;
        ch=getchar();
    }
    return x*f;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    ll temp,p;
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    p=exgcd(b,a%b,x,y);
    temp=x;
    x=y;
    y=temp-(a/b)*y;
    return p;
}
//*******************************
int n,p[1000001];char a[1000001];
int main()
{
    int oo=1;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)break;
        scanf("%s",a+1);
        memset(p,0,sizeof(p));
        int j=0;
        for(int i=2;i<=n;i++)
        {
            while(j>0&&a[j+1]!=a[i])j=p[j];
            if(a[j+1]==a[i])j++;
            p[i]=j;
        }
        cout<<"Test case #"<<oo++<<endl;
        for(int i=2;i<=n;i++)
        {
            if(p[i]>0&&i%(i-p[i])==0){
                cout<<i<<" "<<i/(i-p[i])<<endl;
            }
        }
        cout<<endl;
    }
    return 0;
}

代码

时间: 2024-12-19 11:21:45

UVA 1328 - Period KMP的相关文章

uva 1328 - Period (周期串的判断 kmp)

题意:给一个长为n的字符串,问字符串的前缀是不是周期串,如果是周期串,输出前缀的最后一个字母的位置和最短周期 思路:kmp字符串匹配的性质运用. 对于前i个字符,如果f[i]不等于零,说明在此字符串的前缀中,有一部分[0,f[i]]和本字符串[i-f[i],i]的这一部分是相同的.如果这i个字符组成一个周期串,那么错开的一部分[f[i],i]恰好是一个循环节.(换句话说,如果满足f[i]不等于零 && [f[i],i]是循环节这两点,就可以说明前i个字符组成一个周期串) code: #in

UVa 1328 Period

方法:kmp code: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <string> 6 #include <vector> 7 #include <stack> 8 #include <bitset> 9 #include <cstdlib> 10

LA3026 - Period(KMP)

For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 ≤ i ≤ N) we want to know the largest K > 1 (if the

UVA 1371 - Period(DP)

6.4 一些说明 数据属性可以重写同名的方法属性.这是为了避免在大型系统中产生问题的意外名称冲突.所以用一些减少冲突的常用方法是很有效果的.常用的方法包括:大写字母方法名称,用唯一的字符串来做为数据属性的名称(可以是个下划线_)或者用动词命名方法和用名字命名数据属性. 数据属性就像和对象的普通用户一样可以被方法引用.换句话说,类不能用来实现纯净的数据类型.事实上,在python中不能强制数据隐藏,一切基于约定.(另一方面,如C中写的,python的实现可以做到完全隐藏实现细节并且在必要是可以控制

uva 1371 - Period(二分+dp)

题目链接:uva 1371 - Period 题目大意:给出两个字符串A,B将B分解成若干个子字符串,然后每个子字符串都要变成字符串A,所有子串中编辑最多的次数即为当前状态下的最大编辑次数,要求求最小的最大编辑次数. 解题思路:二分答案,用dp判断,主要是dp判断,dp[i][j]表示到1~i的字符串匹配到j的最大编辑次数,然后考虑分段的时候只要dp[i][0] < mid,那么就可以将dp[i][0] 置0,表示做为起点. #include <cstdio> #include <

UVa 1328 (KMP求字符串周期) Period

当初学KMP的时候也做过这道题,现在看来还是刘汝佳的代码要精简一些,毕竟代码越短越好记,越不容易出错. 而且KMP的递推失配函数的代码风格和后面的Aho-Corasick自动机求失配函数的代码风格也是一致的. 1 #include <cstdio> 2 3 const int maxn = 1000000 + 10; 4 char s[maxn]; 5 int f[maxn]; //失配函数 6 7 int main() 8 { 9 //freopen("in.txt",

uva 1328(kmp)

被打哭了......神特么kmp,还能这么用!看来我理解的还不够透彻,这里最神奇的就是只有相同的字串才能往下延伸,而"i-f[i]"就正好是前面空出来的模板块,也就是f[i]中不计数的那块,而字符串都是从0开始的,对应的往下加一个却正好成立构成倍数关系 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace

uva 1358 - Generator(KMP+期望)

题目链接:uva 1358 - Generator 题目大意:给定n,表示有n中字符,然后给定一个字符串S,一开始字符串为空,现在每次随机生成一个1~n的字符添加到字符串末尾,问说字符串包含S为子串的生成次数期望. 解题思路:首先要对S进行预处理,求出失配数组. 定义dp[i]表示末尾部分匹配了i个S串所需要的次数期望,每次枚举可能出现的字符1~n.对于S字符串,i+1肯定是确定的字符,所以对于其他字符肯定是不匹配的. 假设现在生成了k字符,并且说k字符不等于S[i+1],那么根据S的失配数组,

poj1961 Period kmp解决找字符串的最小循环节

/** 题目:poj1961 Period 链接:http://poj.org/problem?id=1961 题意:求从1到i这个前缀(2<=i<=N) ,如果有循环节(不能自身单独一个),输出前缀字符串长度以及最大的循环周期: 思路: 参考自:http://www.cnblogs.com/chenxiwenruo/p/3546457.html 定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0-len-next[len]-1]. (1)