CF 182D Common Divisors(KMP最短循环节,循环周期)
2012-11-02 00:05
381 查看
链接:
http://codeforces.com/problemset/problem/182/D
题目大意:
假设字符串也有因数,一个字符串S的因数是a,当且仅当S是由k个a连续组成的。 例如S="abababab", 那么"ab"和"abab"都是S的因子。
给两个字符串,求它们的公因数有多少个。
分析总结:
先看看一个数的因子有什么性质。
如果知道了一个最小因子,那么就可以利用这个最小因子求出一个字符串的所有因子。
例如,假设S="abababab", len = |S| = 8, 最小因子为A="ab", minlen = |A| = 2, 除了这个最小因子之外,可以发现S的所有因子长度x必须满足len%x==0,并且,还要再满足x%minlen==0。 “abab”就是S的另外一个因子,它满足这个要求。
利用这个性质,就可以解决这道题了。
首先,分别利用kmp的next数组可以求出两个字符串的最小因数。然后用其中一个去匹配另一个,每次可以得到一个当前已匹配长度j,根据这个j,利用上述性质,如果同时满足两个字符串的因子要求,那么就是他们的一个公因子了。具体看代码。
代码:
—— 生命的意义,在于赋予它意义士。
原创 http://blog.csdn.net/shuangde800 , By
D_Double (转载请标明)
http://codeforces.com/problemset/problem/182/D
题目大意:
假设字符串也有因数,一个字符串S的因数是a,当且仅当S是由k个a连续组成的。 例如S="abababab", 那么"ab"和"abab"都是S的因子。
给两个字符串,求它们的公因数有多少个。
分析总结:
先看看一个数的因子有什么性质。
如果知道了一个最小因子,那么就可以利用这个最小因子求出一个字符串的所有因子。
例如,假设S="abababab", len = |S| = 8, 最小因子为A="ab", minlen = |A| = 2, 除了这个最小因子之外,可以发现S的所有因子长度x必须满足len%x==0,并且,还要再满足x%minlen==0。 “abab”就是S的另外一个因子,它满足这个要求。
利用这个性质,就可以解决这道题了。
首先,分别利用kmp的next数组可以求出两个字符串的最小因数。然后用其中一个去匹配另一个,每次可以得到一个当前已匹配长度j,根据这个j,利用上述性质,如果同时满足两个字符串的因子要求,那么就是他们的一个公因子了。具体看代码。
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long int64; const int MAXN = 100005; char S[MAXN], T[MAXN]; int f1[MAXN],f2[MAXN]; bool vis[MAXN]; void getNext(char* P, int* f){ int n=strlen(P); f[0]=f[1]=0; for(int i=1; i<n; ++i){ int j=f[i]; while(j && P[i]!=P[j]) j=f[j]; f[i+1] = P[i]==P[j]?1+j:0; } } int64 find(char* S,char* P,int* f1,int* f2){ getNext(P,f1); getNext(S,f2); memset(vis, 0, sizeof(vis)); int m=strlen(P); int n=strlen(S); int mp=m%(m-f1[m])?m:(m-f1[m]); int ms=n%(n-f2 )?n:(n-f2 ); int64 cnt=0; int j=0; for(int i=0; i<n; ++i){ while(j && S[i]!=P[j]) j=f1[j]; if(S[i] == P[j]) ++j; if(j && !vis[j]){ if(m%j==0 && n%j==0 && (i+1)%ms==0 && j%mp==0 && j%ms==0){ // 是否满足公因子性质 ++cnt; vis[j]=true; } } } return cnt; } int main(){ scanf("%s %s",S,T); cout << find(S,T,f1,f2) << endl; return 0; }
—— 生命的意义,在于赋予它意义士。
原创 http://blog.csdn.net/shuangde800 , By
D_Double (转载请标明)
相关文章推荐
- hdu 3746 Cyclic Nacklace(KMP 最短循环节)
- HUST 1010 The Minimum Length (KMP 最短循环节)
- POJ 2406 Power Strings(KMP 找最短循环节)
- 数据结构:KMP next数组求串最小循环节、循环周期
- hust--------The Minimum Length (最短循环节)(kmp)
- poj 1961 Period(KMP, 最短循环节)
- UVa1328 - Period(KMP找最短循环节)
- UVA 1328 Period(KMP:最短循环节)
- POJ 1961(KMP, 最短循环节)
- HUST 1010 KMP最短循环节
- HDU 3746 Cyclic Nacklace(KMP,最短循环节)
- POJ 1961 2406 (KMP,最小循环节,循环周期)
- HDU1358 KMP(最短循环节)
- LA 3026 && POJ 1961 Period(KMP求前缀的最短循环节)
- poj 1961 Period(kmp最短循环节)
- poj 1961 Period(kmp最短循环节)
- poj 1961 Period (KMP 最短循环节)
- hust 1010 The Minimum Length (KMP 最短循环节)
- hdu1358(KMP+最小循环节)
- HDU 3746 kmp循环节