HDU 3374 String Problem(最大最小表示+KMP)题解
题意:给你一个字符串,这个字符串可以这样操作:把第一个字符放到最后一个形成一个新的字符串,记原式Rank为1,每操作一步Rank+1,问你这样操作得出的最小字典序的字符串的Rank和这样的字符串有几个,最大字典序的字符串的Rank和这样的字符串有几个。
思路:手动模拟操作复杂度O(n^2)果断超时,引入一种专门计算此情况的方法,复杂度O(n)。
这里只说最小表示:
我们先拿两个指针i,j,分别指向s[0],s[1],将k初始化为0。然后我们循环计算s[i + k]是否等于s[j + k],直到找到一个不等的情况;如果找不到,说明当前已经是最小了。当不相等时,有两种情况:
1.s[i + k]>s[j + k]说明以s[j + k]为开头字典序更小,i移动到该位置,置k = 0
2.s[i + k]<s[j + k]说明s[j]开头不行,j移动到j + k + 1,置k = 0
最后返回min(i,j)
算几个字符串可以用KMP的next数组计算最小循环节解决。
#include<iostream>
#include<algorithm>
const int maxn = 1000000+5;
const int INF = 0x3f3f3f3f;
using namespace std;
int fail[maxn];
char s[maxn],tmp[maxn];
void getFail(char *p){
fail[0] = -1;
int j = 0,k = -1;
int len = strlen(p);
while(j < len){
if(k == -1 || p[j] == p[k]){
fail[++j] = ++k;
}
else{
k = fail[k];
}
}
}
int KMP(char *t,char *p){
getFail(p);
int i = 0,j = 0;
int lent = strlen(t),lenp = strlen(p);
while(i < lent){
if(j == -1 || t[i] == p[j]){
i++;
j++;
if(j == lenp) return 1;
}
else{
j = fail[j];
}
}
return 0;
}
int get_min(char *p){
int len = strlen(p);
int i = 0,j = 1,k = 0;
while(i < len && j <len && k < len){
int t = s[(i + k)%len] - s[(j + k)%len];
if(t == 0) k++;
else{
if(t > 0)
i += k + 1;
else
j += k + 1;
if(i == j) j++;
k = 0;
}
}
return min(i,j);
}
int get_max(char *p){
int len = strlen(p);
int i = 0,j = 1,k = 0;
while(i < len && j <len && k < len){
int t = s[(i + k)%len] - s[(j + k)%len];
if(t == 0) k++;
else{
if(t > 0)
j += k + 1;
else
i += k + 1;
if(i == j) j++;
k = 0;
}
}
return min(i,j);
}
int main(){
while(scanf("%s",s) != EOF){
int len = strlen(s);
int MIN = get_min(s);
int MAX = get_max(s);
for(int i = 0,j = MIN;i < len;i++,j++){
tmp[i] = s[j % len];
}
tmp[len] = '\0';
getFail(tmp);
int c = len - fail[len],ans;
if(len % c == 0) ans = len / c;
else ans = 1;
printf("%d %d ",MIN + 1,ans);
for(int i = 0,j = MAX;i < len;i++,j++){
tmp[i] = s[j % len];
}
tmp[len] = '\0';
getFail(tmp);
c = len - fail[len];
if(len % c == 0) ans = len / c;
else ans = 1;
printf("%d %d\n",MAX + 1,ans);
}
return 0;
}
HDU 3374 String Problem(最大最小表示+KMP)题解的更多相关文章
- hdu 3374 String Problem(最小表示法+最大表示法+kmp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给出一个字符串问这个字符串最小表示的最小位置在哪,还有有几个最小表示的串.最大表示的位置在 ...
- hdu 3374 String Problem (字符串最小最大表示 + KMP求循环节)
Problem - 3374 KMP求循环节. http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html 循环节推导的证明相当 ...
- HDU 3374 String Problem (KMP+最大最小表示)
HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others) Memory ...
- HDU 3374 String Problem(KMP+最大/最小表示)
String Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- HDU - 3374 String Problem (kmp求循环节+最大最小表示法)
做一个高产的菜鸡 传送门:HDU - 3374 题意:多组输入,给你一个字符串,求它最小和最大表示法出现的位置和次数. 题解:刚刚学会最大最小表示法,amazing.. 次数就是最小循环节循环的次数. ...
- HDU 3374 String Problem (KMP+最小最大表示)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3374 [题目大意] 给出一个字符串,求出最小和最大表示是从哪一位开始的,并且输出数量. [题解] ...
- hdu 3374 String Problem(kmp+最小表示法)
Problem Description Give you a string with length N, you can generate N strings by left shifts. For ...
- HDU 3374 String Problem(KMP+最大(最小)表示)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:给出一个字符串,依次左移一个单位形成一堆字符串,求其字典序最小和最大的字符串需要左移多 ...
- hdu 3374 String Problem (kmp+最大最小表示法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小 ...
随机推荐
- JS-制作留言提交系统(支持ctrl+回车)
弹出键值说明: //console.log(ev.keyCode)//回车:13//ctrl:17 <!DOCTYPE html> <html> <head> &l ...
- Codeforces Round #375 (Div. 2)E. One-Way Reform
题目链接:传送门 题目大意:一副无向图,要求你给边定向(变为有向图),使出度等于入度的点最多,输出有多少 个点,并且输出定向后的边(前为起点,后为终点) 题目思路:欧拉路 我们这样考虑,先考虑无向图的 ...
- JavaBean入门及简单的例子
不会编写JavaBean就不是一个Java开发人员. 那么,何谓JavaBean呢? JavaBean是符合某种规范的Java组件,也就是Java类. 它必须满足如下规范: 1)必须有一个零参数的默认 ...
- 2.void 0 与 不可靠的undefined
在 ES5 之前,全局的 undefined 也是可以被修改的,而在 ES5 中,该标识符被设计为了只读标识符, 假如你现在的浏览器不是太老,你可以在控制台中输入以下语句测试一下: undefined ...
- [css]演示:纯CSS实现的右侧底部简洁悬浮效果
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name ...
- Linux创建Python虚拟环境
Linux创建Python虚拟环境 安装 pip install virtualenv 基本使用 为一个工程创建一个虚拟环境: $ cd my_project $ virtualenv venv #v ...
- C++中的.和::和:和->的区别
在学习C++的过程中我们经常会用到.和::和:和->,在此整理一下这些常用符号的区别. 1.A.B则A为对象或者结构体: 2.A->B则A为指针,->是成员提取,A->B是提取 ...
- Redis的一些结构
- WebSocket client for python
Project description websocket-client module is WebSocket client for python. This provide the low lev ...
- Tomcat安装(linux系统)
首先解压: 进入配置文件: 统一tomcat的编码,避免乱码的问题: 保存退出. 注意: 查看打开的端口: /etc/init.d/iptables status 开启端口: iptables -A ...