标签: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