Hdu 3746 循环节 Cyclic Nacklace

原题是英文,咱们按咱们的翻译来哈

有一个字符序列,现在问你:
序列后面最少补充几个元素使其恰能成为几个重复循环的序列。
Input
第一行是一个整数 T ( 0 < T <= 100 ) 代表测试数据的组数. 
之后T行每行一个字符串. 由小写字母'a'-'z'组成. 字符串的长度为: ( 3 <= Len <= 100000 ).
Output
对于每组测试数据,输出一行,即序列后面最少补充几个元素使其恰能成为几个重复循环的序列。
输入样例
3
aaa
abca
abcde
输出样例
0
2
5
Hind
最小循环节(len / (len-next[len]))

此为大佬的暗示

此题妙就妙在有hint(不是hind233333)

我们看图中第一组样例

循环节:4
需要补充:2

然后暗示中公式:6-2=4;

再看第二组:

循环节:2
需要补充:0;

看出来没有啊~

没有的话我补一组

位置 0  1 2 3 4 5 6 7 8 9 10 11 12
内容 A  B A B C A B A B C A  B  &
next-1  0 0 1 2 0 1 2 3 4 5  6  7

然后按照刚才的算式:12-7=5

我们可以发现12就是数组长度len,7就是next[len]的结果,算出来的5呢 就是循环节的长度

那么需要补充循环节怎么算呢

自然就是字符组长度对循环节长度取余咯

那么就有一个问题 该怎么实现呢

首先我们需要计算next

这个直接模板

//为了方便直接定义全局数组,但是记得初始化什么的
string s2;//这个定义在里面经过某人实践会wa 你懂的
int netx[100100];
int len;
void wnetx(){
    int i=0,j=-1;  
    netx[0]=-1;  
    while(i<len){  
        if(j==-1||s2[i]==s2[j]){  
            i++;  
            j++;  
            netx[i]=j;  
        }  
        else j=netx[j];  
    } 
}

今儿上课讲过了 不在多言

然后就是对于情况的判定了

首先计算循环节的长度

int num=len-netx[len];

需要补充的字符长度是

ans=num-len%num;

这里的话我们需要考虑一种情况
假设有一个字符串11111
他的循环节长度是1
我们根据上面的公式计算他需要补充的字符长度是0
但是还有一种情况
假设有一个字符串是12345
他的循环节长度是5
同样,根据上述公式我们计算得到的也是0

那既然这样的话我们就需要特判一下这种情况

可以观察出,第二种情况数组长度和循环节长度相同
所以我们可以这么写

if(len/num==1)
    cout<<len<<endl;
else
    cout<<"0"<<endl;

然后剩下的情况就是特别正常的情况咯

完全代码如下:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
// #define Kongxiangzhouye
#define sd(x) scanf("%d",&x)
#define ss(x) scanf("%s",x)
#define sc(x) scanf("%c",&x)
#define sf(x) scanf("%f",&x)
#define slf(x) scanf("%lf",&x)
#define slld(x) scanf("%lld",&x)
#define me(x,b) memset(x,b,sizeof(x))
#define pd(d) printf("%d\n",d);
#define plld(d) printf("%lld\n",d)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int MAX_N=100000;
const int INF = 0x3f3f3f3f;

string s2;
int netx[100100];
int len;
void wnetx(){
    int i=0,j=-1;  
    netx[0]=-1;  
    while(i<len){  
        if(j==-1||s2[i]==s2[j]){  
            i++;  
            j++;  
            netx[i]=j;  
        }  
        else j=netx[j];  
    } 
}
int main()
{
    #ifdef Kongxiangzhouye
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    while(n--){
        cin>>s2;
        len=s2.length();
        wnetx();
        int num=len-netx[len];
        if(len%num==0)
            if(len/num==1)
                cout<<len<<endl;
            else
                cout<<"0"<<endl;
        else
            cout<<num-len%num<<endl;
    } 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38842456/article/details/79595437
今日推荐