HDU3746-KMP循环节
来源:互联网 发布:java math.random 编辑:程序博客网 时间:2024/05/16 18:05
题目:题目链接
题意:给你一个字符串,要求将字符串的全部字符最少循环2次需要添加的字符数。
例子:
abcabc 已经循环2次,添加数为0
abcac 没有循环2次,添加字符abcac。数目为5.
abcabcab 已经循环过2次,但第三次不完整,需要添加数为1
next函数求法:
void getnext(const char *s){int i = 0, j = -1;nextval[0] = -1;while(i != len){if(j == -1 || s[i] == s[j])nextval[++i] = ++j;elsej = nextval[j];}}
void getnext(const char *p) //前缀函数(滑步函数){int i = 0, j = -1;nextval[0] = -1;while(i != len){if(j == -1 || p[i] == p[j]) //(全部不相等从新匹配 || 相等继续下次匹配){++i, ++j;if(p[i] != p[j]) //abcdabcenextval[i] = j;else //abcabcanextval[i] = nextval[j];}elsej = nextval[j]; //子串移动到第nextval[j]个字符和主串相应字符比较}}
就是求出匹配的串之后,对KMP的循环节和原来的长度比较:
如何利用KMP的next求字符串的循环节
#include <iostream>#include <cstdio>#include <string>#include <string.h>#include <map>#include <vector>#include <cstdlib>#include <algorithm>#include <cmath>#include <queue>#include <set>#include <stack>#include <functional>#include <fstream>#include <sstream>#include <iomanip>#include <numeric>#include <cassert>#include <bitset>#include <stack>#include <ctime>#include <list>#define INF 0x7fffffff#define max3(a,b,c) (max(a,b)>c?max(a,b):c)#define min3(a,b,c) (min(a,b)<c?min(a,b):c)#define mem(a,b) memset(a,b,sizeof(a))using namespace std;int gcd(int n,int m){ if(n<m) swap(n,m); return n%m==0?m:gcd(m,n%m);}int lcm(int n,int m){ if(n<m) swap(n,m); return n/gcd(n,m)*m;}#define N 100010int prime[N];struct node{ int x, y;};bool cmp(const node & a, const node & b){ return a.x > b.x;}void getPrime();void bash();void wzf();void SG();int QuickMod(int a, int b, int n);char num[N];int next[N];int len;void getnext(){ int i = 0, j = -1; next[0] = -1; while(i != len) { if(j == -1 || num[i] == num[j]) next[++i] = ++j; else j = next[j]; }}int main(){ int t; scanf("%d", &t); while(t--) { scanf("%s", num); len = strlen(num); getnext(); int L = len - next[len]; if(len != L && len%L == 0) printf("0\n"); else { int ans = L - next[len]%L; printf("%d\n", ans); } } return 0;}int QuickMod(int a,int b,int n){ int r = 1; while(b) { if(b&1) r = (r*a)%n; a = (a*a)%n; b >>= 1; } return r;}void getPrime(){ memset(prime, 0, sizeof(prime)); prime[0] = 1; prime[1] = 1; for(int i = 2; i < N; ++i) { if(prime[i] == 0) { for(int j = i+i; j < N; j+=i) prime[j] = 1; } }}void bash(int n, int m){ if(n%(m+1) != 0) printf("1\n"); else printf("0\n");}void wzf(int n, int m){ if(n > m) swap(n, m); int k = m-n; int a = (k * (1.0 + sqrt(5.0))/2.0); if(a == n) printf("0\n"); else printf("1\n");}int numsg[N];void SG(int n){ int sum = 0; for(int i=0; i < n; i++) { scanf("%d",&numsg[i]); sum ^= numsg[i]; } if(sum == 0) printf("No\n"); else { printf("Yes\n"); for(int i = 0; i < n; i++) { int s = sum ^ numsg[i]; if(s < numsg[i]) printf("%d %d\n", numsg[i], s);//从有num[i]个石子的堆后剩余s个石子 } }}
- HDU3746-KMP循环节
- 【KMP】【HDU3746】【最小循环节】
- HDU3746--KMP+最小循环节
- 【KMP】 hdu3746 kmp求循环节长度
- hdu3746 利用KMP找循环节
- hdu3746 Cyclic Nacklace KMP判断循环节
- hdu3746 Cyclic Nacklace(kmp找循环节)
- HDU3746 Cyclic Nacklace KMP找循环节
- HDU3746(KMP求循环节)
- HDU3746 Cyclic Nacklace(KMP+最小循环节)
- HDU3746 Cyclic Nacklace(KMP,最小循环节)
- D - Cyclic Nacklace HDU3746 (kmp 计算字符串最小循环节 )
- hdu3746 Cyclic Nacklace(kmp周期 最小循环节)
- [KMP求最小循环节][HDU3746][Cyclic Nacklace]
- hdu3746(KMP)
- hdu3746 KMP
- hdu3746 Cyclic Nacklace (循环节)
- 【HDU3746】【KMP】Cyclic Nacklace 最少添加字符数使得原串出现循环节
- C# 透明窗体制作方法比较(1)
- java并发面试题(一)基础
- 构造函数私有化
- C# 透明窗体制作方法比较(2)
- 字串转换 字符串处理转换 正数减法
- HDU3746-KMP循环节
- 简单的程序诠释C++ STL算法系列: find & find_if
- Listview的onItemClickListener无法响应的解决方法
- linux内核驱动模块的编译及加载
- 什么是Android?
- 黑马程序员——Java基础---String类和基本数据类型包装类
- 【xtku】巧删显卡右键菜单 还系统干净界面
- js 根据模板增加表格(table)
- ubuntu下搭建ftp服务器vsftpd,cuteFTP登录该服务器