hdu 3746 Cyclic Nacklace
http://acm.hdu.edu.cn/showproblem.php?pid=3746
问题描述:字符串增加多少字符实现整个串存在循环节
思路
kmp()中next[]表的理解,前缀与后缀自相匹配的最大长度
len - next[len]是最小的循环节,abcabcabc中为9-6=3;如果len%(len-next[len])==0,则本身存在循环节,周期为len/(len-next[len])
如果没有循环节,如abcdabc,最小循环节L为4,长度7,需要补充L-len%L。
参考代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<sstream>
#define eps 1e-9
#define pi acos(-1)
#define long long ll
using namespace std;
const int _max = 5e4 + 10;
int n,m;
string a,b;
int Next[100010];//大小取决模式串m
void getNext(){//预处理
int i = 0;
int j = Next[0] = -1;
while(i < m){
if(0 > j||b[i] == b[j]) Next[++i] = ++ j;
else j = Next[j];
}
}
int kmp(){//首次匹配成功位置,b是模式串,a是主串,类型不限,
getNext();
int i = 0,j = 0;
while(j < m&& i < n){
if(0 > j||a[i] == b[j]) i++,j++;
else j = Next[j];
}
return i - j;//i-j>n-m匹配失败,成功返回初始匹配位置
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
int T;cin>>T;
while(T--){
cin>>b;
int len = m = b.size();
getNext();//理解next[]表
// for(int i = 0; i <= len; ++ i) printf("%d ",Next[i]);cout<<endl;
if(!Next[len]) {printf("%d\n",len);continue;}
int l = len - Next[len];//最小循环节长度
if(len%l==0) puts("0");
else printf("%d\n",l-len%l);
}
return 0;
}
- 加粗
Ctrl + B
- 斜体
Ctrl + I
- 引用
Ctrl + Q
- 插入链接
Ctrl + L
- 插入代码
Ctrl + K
- 插入图片
Ctrl + G
- 提升标题
Ctrl + H
- 有序列表
Ctrl + O
- 无序列表
Ctrl + U
- 横线
Ctrl + R
- 撤销
Ctrl + Z
- 重做
Ctrl + Y