标签:http course 思路 com imu desc mos log sim
Description
Input
Output
Sample Input
3 aaa abca abcde
Sample Output
0 2 5
题意:给一个字符串,问至少需要增加几个字符使修改后的字符串含有至少两个循环节。
此题给出两个基于KMP的思路。
思路一:发现KMP的前缀next数组len-nxt[len]就是该字符串的最小循环节。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 4;
char s[maxn];
int nxt[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s",&s);
//next数组的构建
int j = 0, k = -1;
int len = strlen(s);
nxt[0] = -1;
while(j<len){
if(k == -1 || s[j] == s[k]){
j++;
k++;
nxt[j] = k;
}
else k = nxt[k];
}
//只有一个循环节
if(nxt[len] == 0){
printf("%d\n",len);
continue;
}
int pos = len - nxt[len];
int res;
//有完整的多个循环节
if(len % pos == 0) res = 0;
//不完整的循环节
else res = pos - len % pos;
printf("%d\n",res);
}
}
思路二:用一个该串作为模板串,从原串的第二个字符去匹配。相差的即为最小循环节。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 4;
char s[maxn];
int nxt[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s",&s);
//构建next数组
int j = 0, k = -1;
int len = strlen(s);
nxt[0] = -1;
while(j<len){
if(k == -1 || s[j] == s[k]){
j++;
k++;
nxt[j] = k;
}
else k = nxt[k];
}
//应用kmp
int i = 1; k = 0;
while(i<len){
while(k != -1 && s[i] != s[k]) k = nxt[k];
++i;
++k;
}
int pos = len - k;
int res = (pos - (len % pos)) % pos;
if(pos == len) res = len;
printf("%d\n",res);
}
}
HDU 3746 Cyclic Nacklace(KMP求循环节)
标签:http course 思路 com imu desc mos log sim
原文地址:http://www.cnblogs.com/bywmm/p/6045214.html