题目请点我

题解:

题目大意:有一个字符串s。能够在前后加入字符,使字符串成为一个循环次数至少为2的循环字符串。输出最少须要加入的字符数目。

首先能够证明题目能够等价为仅仅在末尾加入字符使满足题意。要找到加入资格字符我们首先要找到循环单位的长度。利用一个辅助数组储存从起始位置開始长度为i的串的循环长度,初始值为i,利用与Next数组之间的关系来更新。找到循环长度。比方字符串abcabc,Next[i] = 3,cycle[3] = 3,有等价关系i-Next[i] = cycle[Next[i]];所以循环长度为3.可是注意假设某个字符不能与上一个字符串相应。则须要更新循环长度为当前字符串长度。

例子:

abcdabcda

3

ababac

6

aaaaab

6

代码实现:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MAX 100010 using namespace std; int T;
int res;
int len;
char s[MAX];
int Next[MAX];
int cycle[MAX];
void getnext();
int main(){
scanf("%d",&T);
getchar();
while( T-- ){
gets(s);
len = strlen(s);
getnext();
res = len;
for( int i = 1; i <= len; i++ ){
cycle[i] = i;
int tmp = Next[i];
if( cycle[tmp] == i-tmp ){
cycle[i] = cycle[tmp];
res = cycle[i];
}
else if( res != len && s[i-1] != s[i-res-1] ){
res = cycle[i];
}
}
if( len == res ){
res = len-Next[len]*2;
}
else if( len%res == 0 ){
res = 0;
}
else{
res = res-(len%res);
}
printf("%d\n",res);
}
return 0;
} void getnext(){
memset(Next,0,sizeof(Next));
Next[0] = -1;
int i = 0, j = -1;
while( i < len ){
if( j == -1 || s[i] == s[j] ){
Next[++i] = ++j;
}
else{
j = Next[j];
}
}
return ;
}

另外看到同学的一种递归写法。感觉更巧妙一点,理解起来不太easy。

核心代码:


int solve(int pos){
int tmp = Next[pos]*2;
//无重叠
if( tmp <= pos ){
return pos-tmp;
}
//有重叠
else{
return solve(Next[pos]);
}
}

理解:

对于一个字符串来说,他的前缀串与后缀串分为有重叠和无重叠两种情况。

比方abcabcabc是有重叠;abcab是无重叠,详细关系体如今2*Next与pos大小比較。无重叠我们能够直接输出前缀串与后缀串不同样的部分;对于有重叠我们要递归的向前去找,找到缺少的部分的长度。比方我们用AXBYC表示一个重叠串,当中每一个大写字母表示一个子串,而B为重叠部分,能够证明的是A=B=C,X=Y,作为循环单位缺少的一部分我们要向前递归,知道子串的前缀串与后缀串不再重叠,从而找到X的长度,而特殊情况aaaaaaaaaa。依照上面的定义则他的ABC都是重叠的。所以递归找子问题,直到不再重叠。

HDU_3746 Cyclic Nacklace(KMP)的更多相关文章

  1. HDU 3746 Cyclic Nacklace(kmp next数组运用)

    Cyclic Nacklace Problem Description CC always becomes very depressed at the end of this month, he ha ...

  2. hdu 3746 Cyclic Nacklace KMP循环节

    Cyclic Nacklace 题意:给一个长度为Len( 3 <= Len <= 100000 )的英文串,问你在字符串后面最少添加几个字符可以使得添加后的串为周期串? Sample I ...

  3. HDU3746 Cyclic Nacklace —— KMP 最小循环节

    题目链接:https://vjudge.net/problem/HDU-3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others)    M ...

  4. HDU_3746 Cyclic Nacklace 【KMP的应用】

    一.题目 HDU3746 二.分析 KMP比较好解决的一个问题:如果求一个串中的循环节? 仔细回想KMP的用法,重点是next数组,相当于就是后缀和前缀的比较,那么不正是方便了我们确定循环节? 如果以 ...

  5. hdu3746 Cyclic Nacklace KMP

    CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, ...

  6. Match:Cyclic Nacklace(KMP的next数组的高级应用)(HDU 3746)

    串珠子 题目大意:给定一个字串,要你找到如果要使之成为循环串,在末尾需要的最小的字数(只能添加字符,不能删减字符) 首先联动一下之前做过的动态规划问题POJ 3280,当然了3280这一题是用的LD, ...

  7. HDU 3746 Cyclic Nacklace KMP

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3746 KMP算法—— AC代码: #include <iostream> #include ...

  8. hdu 3746 Cyclic Nacklace(kmp最小循环节)

    Problem Description CC always becomes very depressed at the end of this month, he has checked his cr ...

  9. HDU 3746 Cyclic Nacklace (KMP求循环节问题)

    <题目链接> 题目大意: 给你一个字符串,要求将字符串的全部字符最少循环2次需要添加的字符数. [>>>kmp next函数 kmp的周期问题]  #include &l ...

随机推荐

  1. win10下Spark的环境搭建

    win10下Spark的环境搭建 2018-08-19  18:36:45 一.jdk 1.8.0 安装与配置 二.scala 2.11.8 安装与配置http://www.scala-lang.or ...

  2. BZOJ1801 [Ahoi2009]chess 中国象棋 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1801 题意概括 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请 ...

  3. 如何使用 Git LFS 提交大文件?

    参考资料: An open source Git extension for versioning large files Git LFS的使用 如何使用 Git LFS 提交大文件? Git LFS ...

  4. js时间戳转换时间、距当前时间

    // 1.时间戳转化成时间格式 function getTime(times) { return new Date(parseInt(times) * 1000).toLocaleString().r ...

  5. 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-2 蒙特卡罗(二) 重要性采样

    书本内容:见相册 preface 还记的我们上一篇说的Monte Carlo 维度诅咒吗 上一篇算是二维的例子吧,大家看了之后是否想着写一个一维的Monte Carlo模拟积分?(我想了,没写出来) ...

  6. win 7设置主机域名

    1 Control Panel\Network and Internet\Network Connections right click Local Area Connection<proper ...

  7. BZOJ.1443.[JSOI2009]游戏Game(二分图博弈 匈牙利)

    题目链接 \(Description\) 一个\(N*M\)的有障碍的棋盘,先手放置棋子后,从后手开始轮流移动棋子,不能走重复的位置,不能移动的输.求在哪些位置放棋子是先手必胜的. \(Solutio ...

  8. [CF241E]Flights

    [CF241E]Flights 题目大意: 给一张\(n(n\le1000)\)个点\(m(m\le5000)\)条边的DAG,确定每条边的边权\(w_i(w_i\in\{1,2\})\),使得所有从 ...

  9. [BOI2004]Sequence 数字序列

    Description: Hint: \(n<=10^5\) Solution: 首先考虑b不严格递增时的做法 发现当\(a[i]\)递增时\(b[i]\)直接取\(a[i]\)即可,否则此时需 ...

  10. BZOJ4460 : [Jsoi2013]广告计划

    首先预处理出$f[i][j]$表示第$i$位是字符$j$的字符串集合. 考虑枚举答案$n$,那么模式串中模$n$相同的字符都要按顺序在同一行出现. 设$g[i][j]$表示第$i$列开始出现模$n$为 ...