HDU 3746 KMP_Next 找循环节

题意:给你一个字符串,使添加最少的字符,使得这个字符串由一个循环节循环2次构成。

思路:这道题和POJ 1961差不多,POJ 1961:http://blog.csdn.net/just_water/article/details/12169609

也是找循环节,那么根据POJ 1961的结论,我们很容易推出,当字符串长度为l时,如果next[l] = k ,并且l % (l - k) == 0,那么已经存在循环节,该循环节的长度为(l - k)。

如果不等于0,那么还需要(l - k) - l % (l - k) 这么多的字符,才能使得这个字符串成为循环节为(l - k )的循环串。

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Max 2505
#define FI first
#define SE second
#define ll long long
#define PI acos(-1.0)
#define inf 0x3fffffff
#define LL(x) ( x << 1 )
#define bug puts("here")
#define PII pair<int,int>
#define RR(x) ( x << 1 | 1 )
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )

using namespace std;

#define N 222222

int Next[N] ;
char a[N] ;
void get_Next(){
    Next[0] = -1 ;
    int k = -1 , j = 0 ;
    int l = strlen(a) ;
    while(j < l && k < l){
        if(k == -1 || a[k] == a[j]){
            k ++ ; j ++ ;
            Next[j] = k ;
        }
        else k = Next[k] ;
    }
}
void solve(){
    scanf("%s",a) ;
    get_Next() ;int l = strlen(a) ;
    int k = Next[l] ;
    int d = l - k ;//循环节
    if(k == 0)printf("%d\n",l) ;
    else {
        if(l % d == 0)cout << 0 << endl ;//已经是一个循环节了
        else cout << d - l % d << endl ;//还需要d - l % d 个字符才能成为循环节
    }
}
int main() {
    int _ ; cin >> _ ; while(_ -- )solve() ;
    return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值