hdu4333——拓展kmp
来源:互联网 发布:java 干10年工资多少 编辑:程序博客网 时间:2024/05/01 19:05
题意:给定一个数字序列,不断把后缀移到前面去,组成新的数字序列。问分别由多少个不同的数比原数字小、比原数字大、和原数字相等。
很容易想到拓展kmp的:copy一次原串放后面,对新串求一次extend数组,然后遍历一遍extend数组:extend[i] >= n 说明相等;否则比较str[extend[i]]和str[i + extend[i]]确定与原数的比较结果。
难处理的是怎样把相同的数过滤掉,开始想到了用后缀数组:对height[i] >= n的后缀分组标记出相同的后缀。但还是没写,太繁琐了。后来听说这题卡时限很紧,后缀数组过不了。其实在做kmp的题的时候,应该碰到过这种情况:只有原串中存在循环节,才会遇到上述情况。充分性很好证明,必要性用反证法可以证明。判断循环节的方法很简单,找到第一个i使得i + extend[i] >= n,在判断n % i是否等于零,如果等于零,遍历extend数组的时候到i就可以停止了。
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 200000 + 10;char str[maxn];int extend[maxn];int n;void get_extend(){ extend[0] = 2 * n; for(int i = 1, q = -1, a, p; i < 2 * n; ++i, --q) { if(q < 0 || extend[i - a] >= p - i) { if(q < 0) q = 0, p = i; while(p < 2 * n && str[p] == str[q]) p++, q++; extend[i] = q, a = i; } else extend[i] = extend[i - a]; }}int main(){ freopen("in.txt", "r", stdin); int t, cc= 1; scanf("%d", &t); while(t--) { scanf("%s", str); n = strlen(str); for(int i = 0; i < n; ++i) str[n + i] = str[i]; str[2 * n] = '\0'; get_extend(); int m; for(m = 1; m < n && m + extend[m] < n; ++m); int m1 = (n % m == 0) ? m : n; int l = 0, e = 1, g = 0; for(int i = 1; i < m1; ++i) { int tem = extend[i]; if(tem >= n) e++; else { if(str[i + tem] < str[tem]) l++; else g++; } } printf("Case %d: %d %d %d\n", cc++, l, e, g); } return 0;}/*1341Case 1: 1 1 1*/
- hdu4333——拓展kmp
- hdu4333-拓展kmp-Revolving Digits
- HDU4333:Revolving Digits(拓展kmp)
- 扩展KMP+KMP+hdu4333
- hdu4333之扩展KMP
- 【hdu4333】扩展kmp算法
- hdu4333 扩展kmp
- 扩展kmp(HDU4333)
- hdu4300——拓展kmp
- hdu4333 Revolving Digits(扩展kmp)
- HDOJ 4300 —— 拓展KMP
- HDU4333 Revolving Digits(KMP+扩展KMP)
- HDU4333
- hdu4333 Revolving Digits(kmp+exkmp)
- 【拓展kmp】
- 拓展kmp
- 拓展KMP
- hdu4333 Revolving Digits(扩展kmp+kmp最小循环节)
- Notifiction
- 1035. Password (20)
- firebreah开发插件(同时适用IE和chrome、firefox等非IE)
- 八皇后问题回溯算法
- 二进制,八进制,十进制,十六进制之间转换问题
- hdu4333——拓展kmp
- POJ3062:Celebrity jeopardy
- 1036. Boys vs Girls (25)
- DAY01
- 找出N个数中最大的K个不同的浮点数
- ognl valueStack
- 1037. Magic Coupon (25)
- C语言数据类型及运算符
- 【GamePlay3D】开发指南——部分翻译