题意:http://acm.hdu.edu.cn/showproblem.php?pid=3746
给你一个串,要你在串头或尾添加最少的字符,使得该串至少有2个循环节,问你最少需要加几个字符.
分析:
首先要明白:如果一个串需要至少添加x(x>=0)个字符才能是有>=2个循环节的串,那么我可以只在串末尾添加,不需要去串头添加.(比如串cabc,循环节是abc,我可以在尾部添加ab即可.)
首先如果原始串已经有至少两个循环节就不必添加.当f[m]>0&&m%(m-f[m])==0时,不必添加.(结合之前的KMP循环节题目看看是不是这样.)
现在假设条件 next_s[m]>0&&m%(m-next_s[m])==0 不成立的时候呢?
重要结论:不论串S是不是循环的,如果想要S是一个循环串的话,那么它的最小循环节长度一定是len-f[len]. 其中len是串S的长度.
即不论S是不完整的循环串还是完整的循环串,len-next_s[len]一定是串S中去除末尾残缺部分之后,存在的最小循环节长度.现在来例证一下:
假设f[len]=0,那么是不是该串完全没有由部分子串构成最小循环节呢?是的.
只要一个串是上面的形式a或b,那么就不可能next_s[len]=0.
只要next_s[len]=0 (类似上面的形式c),那么它一定是单独成循环节,需要添加len个字符.
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
//求最小循环节
int next_s[100001];
//求next数组
void getnext(char *s){
memset(next_s,0,sizeof(next_s));
int j=-1,i=0;
next_s[0]=-1;
ll len=strlen(s);
while(i<=len){//一定到len
if(j==-1||s[i]==s[j])next_s[++i]=++j;
else j=next_s[j];
}
}
char s[100001];
int main(){
int n;
cin>>n;
while(n--){
scanf("%s",s);
getnext(s);
ll len=strlen(s);
if(next_s[len]==0){//此字符串本身没有任何循环节
cout<<len<<endl;
continue;
}
int circle_node=len-next_s[len];//最小循环节
int add=circle_node-len%circle_node;//需要补的元素个数
if(len%circle_node==0){
cout<<0<<endl;continue;//本身就是循环节的整数倍
}
cout<<add<<endl;
}
return 0;
}
// /\ | / |**、
// / \ | / | \
// / \ |/ | / _____ ____ | /
// /------\ |\ |__/ / \ \ /\ / / \ | /
// / \ | \ | / \ \ / \ / /______\ |/
// / \ | \ | \ / \ / \ / \ |
// / \ | \ | \_____/ \/ \/ \_____ |
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \| |// `.
// / \||| : |||// \
// / _||||| -:- |||||- \
// | | \\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//