题目大意:给出一个原串长度至少为3,问怎么样在两边添加字符使得成为周期串(周期为2以上),要求添加的字符最少
思路:其实还是一道next数组的灵活运用而已,自己想了几种情况,枚举了下,再利用next数组求了几下..呵呵1A,爽.
1.已经是完整周期的
(1)abab
如果含有周期的,那么直接输出0即可,注意先排除next为1的情况
2.还不是完整周期的
(1)abcabcabca的情况
如果next数组的两倍大于len的话,那么就是有重叠的,但是又不是完整周期的,直接用循环节减去取完模的数即可
(2) abcdfeabc的情况
如果next的两倍都还小于len的话,那么肯定是因为中间有空档,直接输出中间那一部分即可
(3) abcd的情况
next为1的话,直接输出原串的长度
这个规律其实我是做完这道题后的灵感一发:http://blog.youkuaiyun.com/kg_second/article/details/8861777
AC Program:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <queue>
#include <cassert>
typedef long long ll;
#define clr(a) memset((a),0,sizeof (a))
#define rep(i,a,b) for(int i=(a);i<(int)(b);i++)
#define per(i,a,b) for(int i=((a)-1);i>=(int)(b);i--)
#define inf (0x7fffffff)
#define eps 1e-6
#define MAXN
#define MODN (1000000007)
using namespace std;
char t[1000005];
int next[1000005];
void get_next(){
next[1]=0;
int k=0;
int j=1;
int len=strlen(t+1);
while(j<=len){
if(k==0 || t[j]==t[k]){
j++;
k++;
next[j]=k;
}
else{
k=next[k];
}
}
}
int main(){
int test;
cin>>test;
while(test--){
scanf("%s",t+1);//从1开始
int len=strlen(t+1);
get_next();
/*
rep(i,0,len+2){
cout<<next[i]<<" ";
}
cout<<endl;*/
int tmp=len%(len-(next[len+1]-1));
if(tmp==0&&next[len+1]!=1){//如果含有周期的,那么直接输出0即可,注意先排除next为1的情况
cout<<0<<endl;
continue;
}
if((next[len+1])==1){//next为1的话,直接输出原串的长度
cout<<len<<endl;
continue;
}
if(2*(next[len+1]-1)<len){//如果next的两倍都还小于len的话,那么肯定是因为中间有空档,直接输出中间那一部分即可
cout<<len-2*(next[len+1]-1)<<endl;
continue;
}
else{//如果next数组的两倍大于len的话,那么就是有重叠的,但是又不是完整周期的,直接用循环节减去取完模的数即可
cout<<len-(next[len+1]-1)-tmp<<endl;
}
};
//system("pause");
return 0;
}