題目大意:給出一個原串長度至少為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.csdn.net/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;#defineclr(a)memset((a),0,sizeof (a))#definerep(i,a,b)for(int i=(a);i<(int)(b);i++)#defineper(i,a,b)for(int i=((a)-1);i>=(int)(b);i--)#defineinf(0x7fffffff)#defineeps1e-6#defineMAXN#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;}