题意:给你一个字符串,这个字符串可以这样操作:把第一个字符放到最后一个形成一个新的字符串,记原式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)题解的更多相关文章

  1. hdu 3374 String Problem(最小表示法+最大表示法+kmp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给出一个字符串问这个字符串最小表示的最小位置在哪,还有有几个最小表示的串.最大表示的位置在 ...

  2. hdu 3374 String Problem (字符串最小最大表示 + KMP求循环节)

    Problem - 3374   KMP求循环节. http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html   循环节推导的证明相当 ...

  3. HDU 3374 String Problem (KMP+最大最小表示)

    HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  4. HDU 3374 String Problem(KMP+最大/最小表示)

    String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  5. HDU - 3374 String Problem (kmp求循环节+最大最小表示法)

    做一个高产的菜鸡 传送门:HDU - 3374 题意:多组输入,给你一个字符串,求它最小和最大表示法出现的位置和次数. 题解:刚刚学会最大最小表示法,amazing.. 次数就是最小循环节循环的次数. ...

  6. HDU 3374 String Problem (KMP+最小最大表示)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3374 [题目大意] 给出一个字符串,求出最小和最大表示是从哪一位开始的,并且输出数量. [题解] ...

  7. hdu 3374 String Problem(kmp+最小表示法)

    Problem Description Give you a string with length N, you can generate N strings by left shifts. For ...

  8. HDU 3374 String Problem(KMP+最大(最小)表示)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:给出一个字符串,依次左移一个单位形成一堆字符串,求其字典序最小和最大的字符串需要左移多 ...

  9. hdu 3374 String Problem (kmp+最大最小表示法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小 ...

随机推荐

  1. install kubernetes dashboard 安装 kubernetes dashboard 详细

    参考: http://www.bubuko.com/infodetail-2242562.html http://www.cnblogs.com/zhenyuyaodidiao/p/6500897.h ...

  2. 1.执行环境判断 window 或 self

    window or self ? 在 underscore 的判断所处环境的代码中,似乎我们没有看到 window 对象的引用,其实,在浏览器环境下,self 保存的就是当前 window 对象的引用 ...

  3. 边的双联通+缩点+LCA(HDU3686)

    Traffic Real Time Query System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  4. 一键搞定JavaEE应用,JRE+Tomcat+Mysql-JaveEE绿色运行环境JTM0.9版 (转载)

    这是一个集成了jre,tomcat,mysql的绿色运行环境, 直接解压之后就可以运行.不需要用户自己安装jre,tomcat,mysql,一键到位,看起来像是桌面式的web应用.换句话说,就像是we ...

  5. linux启动

    启动顺序:POST加电自检——加载BIOS——读取MBR——GRUB引导——加载kernel——rc0~rc6级别启动——加载内核模块——加载rc.sysinit——inittab运行级别——读取rc ...

  6. VM+CentOS+hadoop2.7搭建hadoop完全分布式集群

    写在前边的话: 最近找了一个云计算开发的工作,本以为来了会直接做一些敲代码,处理数据的活,没想到师父给了我一个课题“基于质量数据的大数据分析”,那么问题来了首先要做的就是搭建这样一个平台,毫无疑问,底 ...

  7. python通过os.walk() 遍历出多级目录下所有文件绝对路径

    代码如下 将遍历出来的路径全部添加到列表中: def get_all_abs_path(source_dir): path_list = [] for fpathe, dirs, fs in os.w ...

  8. 怎么在Linux上抓包分析

    怎么在Linux上抓包分析 1.在Linux上抓包 例如在Ubuntu上,用命令抓包, tcpdump tcp  -i any -s0 -w desk.cap 用  sz desk.cap  把数据包 ...

  9. Python 读取写入配置文件 —— ConfigParser

    Python 读取写入配置文件 —— ConfigParser Python 读取写入配置文件很方便,可使用内置的 configparser 模块:可查看源码,如博主本机地址: “C:/python2 ...

  10. mysqldump 导出统一限制每张数据表导出的记录数

    mysqldump 导出统一限制每张数据表导出的记录数 在工作过程中,需要将生产的数据导出到本地开发环境,我希望可以导出部分数据.而服务器数据量比较大(上千万),如果选择直接从服务器导出数据, 正在运 ...