HDU3746 KMP相同公共前缀和公共后缀的最大长度应用及KMP
2016-04-11 13:31
369 查看
题目大意:在字符串后面最少添加多少个字符可以实现两次循环。
思路:前面有提到过字符串相同公共前缀和公共后缀的最大长度。他的求法和next求法类似,次数也用next数组命名。求得相同前缀和的后缀的最长长度后,进行判断。
如果next[last] = 0,则说明这个字符在前面只出现了一次,必须在结尾加len个字符。若果next[last]刚好可以被字符创长度整除,说明前面已经构成了循环,所以添加0个就好。
最后一种看代码就懂了。
思路:前面有提到过字符串相同公共前缀和公共后缀的最大长度。他的求法和next求法类似,次数也用next数组命名。求得相同前缀和的后缀的最长长度后,进行判断。
如果next[last] = 0,则说明这个字符在前面只出现了一次,必须在结尾加len个字符。若果next[last]刚好可以被字符创长度整除,说明前面已经构成了循环,所以添加0个就好。
最后一种看代码就懂了。
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <fstream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <iomanip> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define maxn 100005 #define MOD 1000000007 #define mem(a , b) memset(a , b , sizeof(a)) #define LL long long #define ULL long long const long long INF=0x3fffffff; char a[maxn]; int Next[maxn]; //ofstream ofile; int main() { int n , t; cin >> t; while(t--) { scanf("%s" , a+1); int m = strlen(a+1); mem(Next , 0); int num = 0; for(int i = 2 ; i <= m ; i ++) { while(num > 0 && a[num + 1] != a[i]) num = Next[num]; if(a[num+1] == a[i]) num++; Next[i] = num; } int min_c = m - Next[m]; if(min_c == m) printf("%d\n" , m); else if(m % min_c == 0) printf("0\n"); else printf("%d\n" , min_c - m % min_c); } return 0; }
相关文章推荐
- 蓝桥杯算法—— 算法训练 前缀表达式
- linux下cat命令详解
- web自己主动保存表单
- 如何:创建公钥/私钥对
- RecyclerView's Note
- 工具类- 身份证校验
- 常用SQL语句的整理--SQL server 2008(查询一)
- sublime text 有毒--无法使用快捷键利用浏览器打开HTML文件
- WPF Toolkit chart控件
- iOS开发之Objective-c的MD5/SHA1加密算法的实现
- 欢迎使用CSDN-markdown编辑器
- C++用类链表模仿栈操作
- mysql设置远程登录
- PHP的诡异与我有太多的约会
- 结对项目:四则运算程序测试
- PHP如何访问数据库集群
- 首尾相接整数数组中最大子数组的和
- Delegation事情委托或代理
- mongoDB使用复制还原数据库节省空间
- lumen 使用 redis缓存