hdu 3746 Cyclic Nacklace KMP中的nex[]应用

来源:互联网 发布:南京市软件行业协会 编辑:程序博客网 时间:2024/04/30 22:57

Cyclic Nacklace

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4718    Accepted Submission(s): 2155


Problem Description
CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, without any surprise, there are only 99.9 yuan left. he is too distressed and thinking about how to tide over the last days. Being inspired by the entrepreneurial spirit of "HDU CakeMan", he wants to sell some little things to make money. Of course, this is not an easy task.

As Christmas is around the corner, Boys are busy in choosing christmas presents to send to their girlfriends. It is believed that chain bracelet is a good choice. However, Things are not always so simple, as is known to everyone, girl's fond of the colorful decoration to make bracelet appears vivid and lively, meanwhile they want to display their mature side as college students. after CC understands the girls demands, he intends to sell the chain bracelet called CharmBracelet. The CharmBracelet is made up with colorful pearls to show girls' lively, and the most important thing is that it must be connected by a cyclic chain which means the color of pearls are cyclic connected from the left to right. And the cyclic count must be more than one. If you connect the leftmost pearl and the rightmost pearl of such chain, you can make a CharmBracelet. Just like the pictrue below, this CharmBracelet's cycle is 9 and its cyclic count is 2:

Now CC has brought in some ordinary bracelet chains, he wants to buy minimum number of pearls to make CharmBracelets so that he can save more money. but when remaking the bracelet, he can only add color pearls to the left end and right end of the chain, that is to say, adding to the middle is forbidden.
CC is satisfied with his ideas and ask you for help.
 

Input
The first line of the input is a single integer T ( 0 < T <= 100 ) which means the number of test cases.
Each test case contains only one line describe the original ordinary chain to be remade. Each character in the string stands for one pearl and there are 26 kinds of pearls being described by 'a' ~'z' characters. The length of the string Len: ( 3 <= Len <= 100000 ).
 

Output
For each case, you are required to output the minimum count of pearls added to make a CharmBracelet.
 

Sample Input
3aaaabcaabcde
 

Sample Output
025
 

Author
possessor WC
 

Source
HDU 3rd “Vegetable-Birds Cup” Programming Open Contest


解题报告:
题意:
给出一个字符串,表示一个项链,现在让你在最左端或最右端添加字符,使该项链至少有两个周期。问最小添加的字符数量(可以为0)

思路:
1.因为是项链,是个环,所以 往左边添加和往右边添加不影响答案。
2.左思右想,想出来一个真理:如果字符串足够长 ,那么nex[x]+1到x  这段字符串  会作为一个周期,从x处开始向左不断循环、重复出现。
最左边可能没有一个完整的周期。
3.因为是往原有的项链上加字符,必须在最后一位用 nex[x]-x 作为周期,从而计算所需添加的字符个数。
4.添加后至少要有两个周期。
5.如果3是周期长度,那么不可能5也是周期,但6是周期。
6.x-nex[x]求的是最小周期。
#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<climits>#include<queue>#include<vector>#include<map>#include<sstream>#include<set>#include<stack>#include<cctype>#include<utility>#pragma comment(linker, "/STACK:102400000,102400000")#define PI 3.1415926535897932384626#define eps 1e-10#define sqr(x) ((x)*(x))#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)#define  lson   num<<1,le,mid#define rson    num<<1|1,mid+1,ri#define MID   int mid=(le+ri)>>1#define zero(x)((x>0? x:-x)<1e-15)#define mk    make_pair#define _f     first#define _s     secondusing namespace std;//const int INF=    ;typedef long long ll;//const ll inf =1000000000000000;//1e15;//ifstream fin("input.txt");//ofstream fout("output.txt");//fin.close();//fout.close();//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);const int INF =0x3f3f3f3f;const int maxm= 100000+10   ;//const int maxm=    ;char M[maxm];int len,nex[maxm];void getnex(){    nex[0]=-1;    for(int i=1;i<=len;i++)    {        int p=nex[i-1];        while(~p&&M[p+1]!=M[i]) p=nex[p];        nex[i]=p+1;    }}int main(){    int T;scanf("%d",&T);    while(T--)    {        scanf("%s",M+1);        len=strlen(M+1);        getnex();        int circle=len-nex[len];        int ans= (circle-len%circle)%circle;        if(nex[len]==0) ans=len;        printf("%d\n",ans );    }    return 0;}


 
0 0
原创粉丝点击