HDU 5442 Favorite Donut 最大表示法+KMP
2016-07-13 09:34
411 查看
首先2次最大表示法求出顺序和逆序情况下的位置,不过逆序求出来的是最大的下标,可以利用循环节来推出最小的位置。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000010; int f[maxn]; char s[maxn]; void getFail(char p[]) { int m = strlen(p); f[0] = f[1] = 0; for(int i = 1; i < m; i++) { int j = f[i]; while(j && p[i] != p[j]) j = f[j]; f[i+1] = p[i] == p[j] ? j+1 : 0; } } int min_exp(char str[]) { int i = 0, j = 1, len, k = 0; len = strlen(str); while(i < len && j < len && k < len) { int t = str[(i+k)%len] - str[(j+k)%len]; if(!t) k++; else { if(t > 0) i = i + k + 1; else j = j + k + 1; if(i == j) j++; k = 0; } } return i > j ? j : i; } int max_exp(char str[]) { int i = 0, j = 1, len, k = 0; len = strlen(str); while(i < len && j < len && k < len) { int t = str[(i+k)%len] - str[(j+k)%len]; if(!t) k++; else { if(t < 0) i = i + k + 1; else j = j + k + 1; if(i == j) j++; k = 0; } } return i > j ? j : i; } char s1[22222], s2[22222]; int main() { int T; scanf("%d", &T); while(T--) { int len; scanf("%d %s", &len, s); getFail(s); int l = len-f[len]; int p1 = max_exp(s); for(int i = p1, j = 0; j < len; j++, i = (i+1)%len) { s1[j] = s[i]; } s1[len] = 0; reverse(s, s+len); int p2 = max_exp(s); for(int i = p2, j = 0; j < len; j++, i = (i+1)%len) { s2[j] = s[i]; } s2[len] = 0; int ans = len%l == 0 ? l : len; p2 = len-p2-1; int dir = 0; p1 %= ans; p2 %= ans; if(strcmp(s1, s2) < 0 || strcmp(s1, s2) == 0 && p1 > p2) { p1 = p2; dir = 1; } printf("%d %d\n", p1+1, dir); } return 0; }
相关文章推荐
- Shiro配置
- Missing artifact log4j:log4j:bundle:1.2.17
- POJ 1904 King's Quest 强连通分量+二分匹配
- linux-SSH远程服务的管理操作,查看虚拟机信息
- Bzoj3509:[CodeChef] COUNTARI:分块+FFT
- POJ 2486 Apple Tree 树形DP
- Android Hook框架Xposed原理与源代码分析
- Vim C/C++自动提示插件
- 网络流模板 Dinic+ISAP
- CodeForces 526B Om Nom and Dark Park
- 算法01之归并排序及多线程测试
- 亚马逊开源 AWS 平台无服务器微框架
- 定义类的方式
- 第09章:集合
- 在leangoo里怎么创建看板,更改看板名称?
- 无监督机器学习--Ipython notebook
- μC/OS-Ⅱ之任务控制块、任务就绪表
- 字典序生成排列
- 如何评审功能测试用例
- MapReduce环境、原理、架构及操作