hdu3374 String Problem【最小表示法】【exKMP】
String Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4828 Accepted Submission(s): 1949
String Rank
SKYLONG 1
KYLONGS 2
YLONGSK 3
LONGSKY 4
ONGSKYL 5
NGSKYLO 6
GSKYLON 7
and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once.
Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
aaaaaa
ababab
1 6 1 6
1 3 2 3
题意:
找到给定的字符串$S$的最小表示法和最大表示法。并且找到他在所有循环同构串中的出现次数。
思路:
首先肯定是要先分别找出最大表示法和最小表示法对应的起始下标。
方法就是先复制一倍接在后面,然后用两个指针分别从0和1开始往后扫描,在第一个发现不相等的位置比较$s[i+k]$和$s[j+k]$的大小。
然后用exKMP分别对最小表示法和最大表示法求$extend$数组。
然后数一下有多少个$extend[i] = n$,这就是个数。
#include<iostream>
#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
//#include<cstdlib>
#include<cstring>
#include<algorithm>
//#include<queue>
#include<vector>
//#include<set>
//#include<climits>
//#include<map>
using namespace std;
typedef long long LL;
#define N 100010
#define pi 3.1415926535
#define inf 0x3f3f3f3f const int maxn = 1e6 + ;
char s[maxn * ], t[maxn];
int nxt[maxn * ], ex_min[maxn * ], ex_max[maxn * ]; void GETNEXT(char *str)
{
int i=,j,po,len=strlen(str);
nxt[]=len;//初始化next[0]
while(str[i]==str[i+]&&i+<len)//计算next[1]
i++;
nxt[]=i;
po=;//初始化po的位置
for(i=;i<len;i++)
{
if(nxt[i-po]+i<nxt[po]+po)//第一种情况,可以直接得到next[i]的值
nxt[i]=nxt[i-po];
else//第二种情况,要继续匹配才能得到next[i]的值
{
j=nxt[po]+po-i;
if(j<)j=;//如果i>po+next[po],则要从头开始匹配
while(i+j<len&&str[j]==str[j+i])//计算next[i]
j++;
nxt[i]=j;
po=i;//更新po的位置
}
}
}
//计算extend数组
void EXKMP(char *s1,char *s2, int *ex)
{
int i=,j,po,len=strlen(s1),l2=strlen(s2);
GETNEXT(s2);//计算子串的next数组
while(s1[i]==s2[i]&&i<l2&&i<len)//计算ex[0]
i++;
ex[]=i;
po=;//初始化po的位置
for(i=;i<len;i++)
{
if(nxt[i-po]+i<ex[po]+po)//第一种情况,直接可以得到ex[i]的值
ex[i]=nxt[i-po];
else//第二种情况,要继续匹配才能得到ex[i]的值
{
j=ex[po]+po-i;
if(j<)j=;//如果i>ex[po]+po则要从头开始匹配
while(i+j<len&&j<l2&&s1[j+i]==s2[j])//计算ex[i]
j++;
ex[i]=j;
po=i;//更新po的位置
}
}
} int main()
{
while(scanf("%s", s) != EOF){
int n = strlen(s);
for(int i = ; i < n; i++)s[n + i] = s[i];
int i = , j = , k;
while(i < n && j < n){
for(k = ; k < n && s[i + k] == s[j + k]; k++);
if(k == n)break;
if(s[i + k] > s[j + k]){
i = i + k + ;
if(i == j)i++;
}
else{
j = j + k + ;
if(i == j)j++;
}
}
int rnk_min = min(i, j); i = , j = ;
while(i < n && j < n){
for(k = ; k < n && s[i + k] == s[j + k]; k++);
if(k == n)break;
if(s[i + k] > s[j + k]){
j = j + k + ;
if(i == j)j++;
}
else{
i = i + k + ;
if(i == j)i++;
}
}
int rnk_max = min(i, j); int min_cnt = ;
memcpy(t, s + rnk_min, n);
EXKMP(s, t, ex_min);
for(int i = ;i < n; i++){
if(ex_min[i] == n)min_cnt++;
}
int max_cnt = ;
memcpy(t, s + rnk_max, n);
EXKMP(s, t, ex_max);
for(int i = ; i < n; i++){
if(ex_max[i] == n)max_cnt++;
}
printf("%d %d %d %d\n", rnk_min + , min_cnt, rnk_max + , max_cnt);
}
return ;
}
hdu3374 String Problem【最小表示法】【exKMP】的更多相关文章
- hdu String Problem(最小表示法入门题)
hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include &l ...
- HDU3374 String Problem —— 最小最大表示法 + 循环节
题目链接:https://vjudge.net/problem/HDU-3374 String Problem Time Limit: 2000/1000 MS (Java/Others) Me ...
- hdu3374 String Problem 最小最大表示法 最小循环节出现次数
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int ...
- HDU - 3374:String Problem (最小表示法模板题)
Give you a string with length N, you can generate N strings by left shifts. For example let consider ...
- hdu3374 String Problem KMP+最大最小表示法
Give you a string with length N, you can generate N strings by left shifts. For example let consider ...
- HDU-3374-String Problem(最小表示法, KMP)
链接: https://vjudge.net/problem/HDU-3374 题意: Give you a string with length N, you can generate N stri ...
- hdu3374 String Problem
地址:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目: String Problem Time Limit: 2000/1000 MS (Java/ ...
- HDU3374 字符串最大最小表示法模板
一开始没太看懂什么意思,拿笔反复推了一遍才大概知道最大最小表示法是怎么求的,感觉太神奇了... #include <iostream> #include <cstdio> #i ...
- 2019牛客暑期多校训练营(第七场)A.String【最小表示法】
传送门:https://ac.nowcoder.com/acm/contest/887/A 题意:大意就是给你一个只含有0和1的字符串,找出一种分割方法,使得每个分割出的字符串都是在该字符串自循环节中 ...
随机推荐
- ERROR: Field * doesn't have a default value
ERROR: Field 'status' doesn't have a default value 今天做项目,在插入数据时出现了这个从没遇到的异常,看了98%的异常分析都是针对组件id出现了类似的 ...
- OpenLayers典型部分概述
中文学习:http://www.openlayers.cn/portal.php 原文地址:https://www.jianshu.com/p/e693711a7008 一 OpenLayers核心职 ...
- win8使用技巧
windows 8操作系统相信大家已经不再陌生了,虽然正式版本还未发布,但不少朋友已经在使用微软事先推出的windows 消费者预览版,直白的说就是公测版,预览版是免费的,但仅可以使用一年,但其功能与 ...
- 读取Excel二进制写入DB,并从DB中读取生成Excel文件
namespace SendMailSMSService { class Program { static void Main(string[] args) { var connString = Sq ...
- linux每日命令(19):locate 命令
locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案.其方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就只需查询这个数据库,而不必实际深入档案系统之中了.在一般的 di ...
- 为什么watch机制不是银弹?
几乎所有构建系统都选择使用watch机制来解决开发过程中需要反复生成构建后文件的问题,但在watch机制下,长期以来我们必须忍受修改完代码,保存完代码必须喝口茶才能刷新看看效果的问题.在这里我们尝试探 ...
- JVM 内部原理(七)— Java 字节码基础之二
JVM 内部原理(七)- Java 字节码基础之二 介绍 版本:Java SE 7 为什么需要了解 Java 字节码? 无论你是一名 Java 开发者.架构师.CxO 还是智能手机的普通用户,Java ...
- Go_14:GoLang中 json、map、struct 之间的相互转化
1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母 ...
- 缓存Memcached 与 Redis 相同点差异点分析
memcach简介 Memcache时一个内存对象缓存系统,用于加速动态web应用程序,减轻数据库负载.它可以应对任意多个连接,使用非阻塞的网络I/O,工作机制:在内存中开辟一块空间,然后建立一个ha ...
- python风格的抽象工厂模式
抽象工厂模式: 提供一个接口,用户创建多个相关或依赖对象,而不需要指定具体类. 原则: 依赖抽象,不依赖具体类. 实例: 用不同原材料制作不同口味的披萨,创建不同原材料的工厂,不同实体店做出口味不同的 ...