hdu3374最小表示法+KMP
题意:
给你一个最长100W的串,然后让你找到最小同构子串,还有最大同构子串的下标,最小同构子串就是把字符串连接成一个环,然后选择一个地方断开,得到的一个ASCII最小的子串(求最大同理),得到两个下标之后还要求两个数,就是最小子串出现的次数,还有最大子串出现的次数,就是所有循环移位后的到的len个子串中最小子串出现了多少次?
思路:
求最小和最大小标这个可以用最小表示法来求(求最大就是把最小表示法稍微改一下),而求出现次数可以用KMP来求,出现次数等于最大周期数,为什么等于这个可以这样想
abcabcabc 循环移位 bcabcabca 继续 cabcabcab 继续 abcabcabc三次就得到一个一样的了,那么也就是说这个串中的任何循环移位串只要三次就会出现一样的,本来总个数是len,每三个一样是不是就是每个串出现len/3,这个三是不是就是我们KMP里面说的那个最小循环节。len/最小循环节 不就是最小循环节的周期数吗? so..直接KMP搞定次数,任何串出现的次数都是一样的,最后再返回来说下最小表示法。
最小表示法可以直接求出来自小的(或者是最大的)循环移位串的首字母是的下标,
比如dabc的小标就是2(从1开始)
核心代码很短
int GetMinId(char *str)
{
int i = 0 ,j = 1 ,k = 0;
while(i < len && j < len && k < len)
{
int t = str[(i+k)%len] - str[(j+k)%len];
if(!t) ++k;
else
{
t > 0 ? i = i + k + 1 : j = j + k + 1;
if(i == j) j ++;
k = 0;
}
}
return i < j ? i : j;
}
可以这么理解,先定义两个变量i,j表示的都是前缀的下标,每次更新的时候我们把不满足的下标往后更新,就是往后+,最后得到前面的那个小的就是答案,关键是为什么?
我是这样想的
首先核心就是
if(t > 0) i = i + k + 1;
else j = j + k + 1;
这个地方是什么情况,比如i代表的串是 abcd j代表的串是abca此时的k肯定是3那么t>0这个时候i直接跳到d的后面,也就是i = i + k + 1,就是默认之间的都肯定不是答案,这个是关键,为什么之间的bcd都肯定不是答案的起点呢,原因是abcd 和abca比较的时候到k=3的时候发现不相等了,那么之前的一定是相等的,那么也就是说i的串的a和d之间的bcd当串首字母的时候肯定会被j的串abca中的bc当首字母比下去,因为bcd<bca cd< ca d < a就是没有必要再比较了,这个一开始可能很不容易理解,但是仔细想想会明白的,我说的是我自己的理解,也有可能有错误,还有就是提示一点,如果实在理解不了这个方法可以先写一个暴力的,然后在想,我就是这么干的,顺便给一个暴力的代码吧,暴力的很多时候也可以过题目,只不过要看数据。
int GetMinId(char * str)
{
int len = stelen(str);
int i = 0 ,j = 1 , k = 0;
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 = j;
j ++;
k = 0;
}
}
return i;
}
下面是hdu3374代码
#include<stdio.h>
#include<string.h>
#define N 1000000 + 10
char str[N];
int next[N];
void GetNext(int m ,char *str)
{
int j = 0 ,k = -1;
next[0] = -1;
while(j < m)
{
if(k == -1 || str[j] == str[k])
next[++j] = ++k;
else k = next[k];
}
}
int GetMinId(int len ,char *str)
{
int i = 0 ,j = 1 ,k = 0;
while(i < len && j < len && k < len)
{
int t = str[(i+k)%len] - str[(j+k)%len];
if(!t) ++k;
else
{
t > 0 ? i = i + k + 1 : j = j + k + 1;
if(i == j) j ++;
k = 0;
}
}
return i < j ? i : j;
}
int GetMaxId(int len ,char *str)
{
int i = 0 ,j = 1 ,k = 0;
while(i < len && j < len && k < len)
{
int t = str[(i+k)%len] - str[(j+k)%len];
if(!t) ++k;
else
{
t < 0 ? i = i + k + 1 : j = j + k + 1;
if(i == j) j ++;
k = 0;
}
}
return i < j ? i : j;
}
int main ()
{
int len;
while(~scanf("%s" ,str))
{
len = strlen(str);
GetNext(len ,str);
int max = GetMaxId(len ,str) + 1;
int min = GetMinId(len ,str) + 1;
int c;
if(next[len] && len % (len - next[len]) == 0)
c = len / (len - next[len]);
else c = 1;
printf("%d %d %d %d\n" ,min ,c ,max ,c);
}
return 0;
}
hdu3374最小表示法+KMP的更多相关文章
- Hdu 5442 Favorite Donut (2015 ACM/ICPC Asia Regional Changchun Online 最大最小表示法 + KMP)
题目链接: Hdu 5442 Favorite Donut 题目描述: 给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果 ...
- HDU-3374-String Problem(最小表示法, KMP)
链接: https://vjudge.net/problem/HDU-3374 题意: Give you a string with length N, you can generate N stri ...
- hdu3374 最大最小表示法 +kmp
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio&g ...
- 【HDU3374】 String Problem (最小最大表示法+KMP)
String Problem Description Give you a string with length N, you can generate N strings by left shift ...
- hdu3374 String Problem KMP+最大最小表示法
Give you a string with length N, you can generate N strings by left shifts. For example let consider ...
- hdu3374 kmp+最小表示法
Give you a string with length N, you can generate N strings by left shifts. For example let consider ...
- hdu-3374(kmp+最小表示法)
题意:给你一个字符串,这个字符串我们可以把把他变成n个字符串按照以下规则:将当前字符串第一个放到字符串最后一位,字符串的下标依次向前推一位,比如:s[1] s[2 ]s[3] s[4]->s[2 ...
- HDU 3374 最小/大表示法+KMP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给定一个串s,该串有strlen(s)个循环同构串,要求输出字典序最小的同构串的下标,字典 ...
- hdu5442(2015长春赛区网络赛1006)后缀数组+KMP /最小表示法?
题意:给定一个由小写字母组成的长度为 n 的字符串,首尾相连,可以从任意一个字符开始,顺时针或逆时针取这个串(长度为 n),求一个字典序最大的字符串的开始字符位置和顺时针或逆时针.如果有多个字典序最大 ...
随机推荐
- 翻译:《实用的Python编程》04_00_Overview
目录 | 上一节 (3 程序组织) | 下一节 (5 Python对象的内部工作原理) 4. 类和对象 到目前为止,我们的程序仅使用了内置的 Python 数据类型.本节,我们介绍类(class)和对 ...
- 修改 Hosts 解决 Github 访问缓慢问题
背景 最近访问 Github 经常出现访问速度慢的问题,甚至会出现无法连接的情况.有一天,在一次家常聊天中提到了这个事情,有一位热心的 Gitee 朋友就说:你改一下 Hosts 文件就可以了.修改了 ...
- golang 三维向量相关操作
package vector import ( "math" "fmt" )// 三维向量:(x,y,z) type Vector3 struct { X fl ...
- python 集合详解
字符串 一个个字符组成的有序的序列,时字符的集合 使用单引,双引,三引 引住的字符序列 字符时不可变的对象 bytes定义 bytes不可变字节序列 使用b前缀定义 只允许基本ASCII使用字符形式 ...
- 技术分享PPT整理(一):Bootstrap基础与应用
最近在复习的时候总感觉有些知识点总结过,但是翻了一下博客没有找到,才想起来有一些内容是放在部门的技术分享里的,趁这个时候跳了几篇相对有价值的梳理一下,因为都是PPT,所以内容相对零散,以要点和图片为主 ...
- OpenGL光照计算中法线矩阵原理及推到过程
问题起源 在计算漫反射关照时,需要用到法线,通过法线和光线的点乘值,计算漫反射的产生的光线强度,所以需要从顶点着色器中将法线数据传递到片源着色器中,但是片源着色器中的顶点坐标是经过了模型矩阵变化过的世 ...
- 美图录爬虫(requests模块,re模块)
Python 爬虫 最近学正则表达式,刚好知道这个网站美图录,就做了个爬虫拿来练练手,说一说遇到的问题 一 404问题 问题: 由于图片显示页面是分页的,每一页展示5张图片,为了方便没有每次去获取下一 ...
- Java学习之路 -- Java怎么学?
@ 目录 java基础怎么学? 学完基础学什么? 几个常用框架学完学什么? MQ JVM的知识跑不掉 微服务等等 其他 数据结构和算法 java基础怎么学? 当时,作为懵懂的小白,大一学习了c和c++ ...
- 在M1芯片的Mac系统上做.net core开发靠谱吗?
作为一个7年老.NET程序员,最近几年苹果慢慢接替微软,成为我心中最酷的科技公司. 为什么我会选择Mac os作为我的开发环境? 很多做.net的同学都使用Windows系统作为自己的开发环境,我其实 ...
- 最短路径(Floyd算法)
声明:图片及内容基于https://www.bilibili.com/video/BV1oa4y1e7Qt?from=articleDetail 多源最短路径的引入 Floyd算法 原理 加入a: 加 ...