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 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小 ...
随机推荐
- stringstream读入每行数据
做了下阿里的编程测试题,就30分钟,不是正常的输入输入,直接给一个数组作为输入. 于是带想题和处理数据花了20分钟,最后10分钟搞一个dij模版, 竟然只过了66%,应该是我数组开小了. 题目数据量没 ...
- hql 语法与详细解释<转>
HQL查询 HQL查询: Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性 ...
- 主流品牌服务器(Dell、HP、IBM)远程管理卡IP配置参考
版权声明:个人网络收集整理,欢迎转载! https://blog.csdn.net/niufenger/article/details/80737878 ※Dell服务器iDRAC IP配置 ※HP服 ...
- jdbc将数据库连接信息放置配置文件中
目录如下: jdbcConnection.java: package jdbc01; import java.io.InputStream; import java.sql.Connection; i ...
- vscode 代码保存时自动格式化成 ESLint 风格
vscode 的默认的代码格式化 alt+shift+f (windows) 无法通过 eslint 的代码风格检查,,, 比如: 4个空格和2个空格(ESLint) 字符串用单引号(ESLint) ...
- Web界面的服务器监测工具(转载)
企业服务器对于企业业务持续性意义重大,系统管理员需要密切关注企业服务器以确保一切正常运行.当发现问题的时候,他们需要知道问题开始出现时的状况,因此调查可以重点放在问题出现的时候,这就意味着定期记录信息 ...
- 【git】------git的基本命令------【巷子】
001.初始化仓库,创建git仓库 git init 002.配置个人信息 git config --global user.name <名字> --------->:配置用户名 g ...
- vuls漏洞扫描工具
Vuls 是一款适用于 Linux/FreeBSD 的漏洞扫描程序,无代理,采用 Go 语言编写,对于系统管理员来说,每天必须执行安全漏洞分析和软件更新都是一个负担. 为避免生产环境宕机,系统管理员通 ...
- Oracle Schema Objects——PARTITION
Oracle Schema Objects 表分区 表- - 分区( partition )TABLE PARTITION 一段时间给出一个分区,这样方便数据的管理. 可以按照范围range分区,列表 ...
- 使用docx4j编程式地创建复杂的Word(.docx)文档
原文链接:Create complex Word (.docx) documents programatically with docx4j 原文作者:jos.dirksen 发表日期:2012年2月 ...