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-两周内自动登录功能
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- LeetCode——Count Complete Tree Nodes
Description: Given a complete binary tree, count the number of nodes. In a complete binary tree ever ...
- 详解struts2中配置action的方法
如何解决action太多的问题??我们因为需要不同的方法,所以往往建立很多不同的类,但是每个类中往往仅仅几行代码,不仅浪费了时间,而且配置起来也很繁琐,所以,建立一个共有的类,然后根据以下方式来操作, ...
- select标签的onchange事件
/** @1.onchange事件 ==> select选择事件* @2.obj.options ==> 选择option集合* @3.obj.selectedIndex ==> 选 ...
- 使用object literal替换switch
提问: 1.为什么要使用switch方法 ==> (替换冗长的if和else判断) 2.什么场景下使用 ==> (在判断布尔值的) 3.switch有什么优点 ==> (简化了代码 ...
- 【BZOJ2901】矩阵求和
Description 给出两个n*n的矩阵,m次询问它们的积中给定子矩阵的数值和. Input 第一行两个正整数n,m. 接下来n行,每行n个非负整数,表示第一个矩阵. 接下来n行,每行n个非负整数 ...
- Python - 3.6 学习第一天
开始之前 基础示例 Python语法基础,python语法比较简单,采用缩紧方式. # print absolute value of a integer a = 100 if a >= 0: ...
- 170623、springboot编程之JdbcTemplate操作数据库
使用JdbcTemplate操作mysql数据库! 1.在pom中引入jpa包 <dependency> <groupId>org.springframework.boot&l ...
- Asp.net底层机制
Asp.net底层就是用户通过输入网址,然后请求IIs服务器的流程,在这个过程中有一个重要的部件就是ISAPI,这是一个底层的win32API,在扩展方面比较困难,多用于接口之间的桥接,.net和II ...
- 利用Dockerfile构建一个基于CentOS 7镜像
利用Dockerfile构建一个基于CentOS 7,包括java 8, tomcat 7,php ,mysql+mycat的镜像. Dockerfile内容如下: FROM centosMAINTA ...