String Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4828    Accepted Submission(s): 1949

Problem Description
Give you a string with length N, you can generate N strings by left shifts. For example let consider the string “SKYLONG”, we can generate seven strings:
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.
 
Input
  Each line contains one line the string S with length N (N <= 1000000) formed by lower case letters.
 
Output
Output four integers separated by one space, lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), the string’s times in the N generated strings, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
 
Sample Input
abcder
aaaaaa
ababab
 
Sample Output
1 1 6 1
1 6 1 6
1 3 2 3
 
Author
WhereIsHeroFrom
 
Source

题意:

找到给定的字符串$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】的更多相关文章

  1. hdu String Problem(最小表示法入门题)

    hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include &l ...

  2. HDU3374 String Problem —— 最小最大表示法 + 循环节

    题目链接:https://vjudge.net/problem/HDU-3374 String Problem Time Limit: 2000/1000 MS (Java/Others)    Me ...

  3. hdu3374 String Problem 最小最大表示法 最小循环节出现次数

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; int ...

  4. HDU - 3374:String Problem (最小表示法模板题)

    Give you a string with length N, you can generate N strings by left shifts. For example let consider ...

  5. hdu3374 String Problem KMP+最大最小表示法

    Give you a string with length N, you can generate N strings by left shifts. For example let consider ...

  6. HDU-3374-String Problem(最小表示法, KMP)

    链接: https://vjudge.net/problem/HDU-3374 题意: Give you a string with length N, you can generate N stri ...

  7. hdu3374 String Problem

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目: String Problem Time Limit: 2000/1000 MS (Java/ ...

  8. HDU3374 字符串最大最小表示法模板

    一开始没太看懂什么意思,拿笔反复推了一遍才大概知道最大最小表示法是怎么求的,感觉太神奇了... #include <iostream> #include <cstdio> #i ...

  9. 2019牛客暑期多校训练营(第七场)A.String【最小表示法】

    传送门:https://ac.nowcoder.com/acm/contest/887/A 题意:大意就是给你一个只含有0和1的字符串,找出一种分割方法,使得每个分割出的字符串都是在该字符串自循环节中 ...

随机推荐

  1. React Native 设置RGBA背景色

    React Native 设置RGBA背景色: 可以先用Mac自带吸色工具,获取RGB值,然后设置背景如下: backgroundColor: 'rgba(52, 52, 52, 0.8)', 透明度 ...

  2. 一道简单的python面试题-购物车

    要求实现:1.程序开始运行时要求手动填入工资金额2.然后展示一份带有价格的商品列表3.选择某个商品,足够金额购买就添加到购物车,否则提示无法购买4.退出后列出购物车清单 #!/usr/bin/pyth ...

  3. 第三部分:Android 应用程序接口指南---第二节:UI---第三章 菜单

    第3章 菜单 在许多不同类型的应用中,菜单通常是一种用户界面组件.为了提供给用户提供熟悉且一致的体验,你需要使用菜单API来展示用户动作和你Activity中的其他选项. 从安卓3.0系统(API l ...

  4. Egret里用矢量挖圆形的洞

    项目里需要用到,但是不是用在新手引导上,下面的代码可以绘制一个圆的四分之一,用四个即可拼出一个圆. private createShape(): egret.Shape { let magicNum ...

  5. System.SerializableAttribute

    System.SerializableAttribute 串行化是指存储和获取磁盘文件.内存或其他地方中的对象.在串行化时,所有的实例数据都保存到存储介质上,在取消串行化时,对象会被还原,且不能与其原 ...

  6. (转) mysql中left join,right join,inner join的区别

    转自:https://blog.csdn.net/qq_35975416/article/details/78842958 sql查询中有一个非常重要的环节就是表的关联查询,一般使用left join ...

  7. linux每日命令(37):top命令

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法.top是一个动态显示过程,即可以通过用户按键来不断刷新 ...

  8. mxnet:基础知识和一个简单的示例

    NDArray与NumPy的多维数组类似,但NDArray提供了更多的功能:GPU和CPU的异步计算:自动求导.这使得NDArray能更好地支持机器学习. 初始化 from mxnet import ...

  9. cocos2d-x 重力感应

    本文没你想象的那么,,复杂.事实上就是通过重力感应控制个小球移动而已. 先看头文件: #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE ...

  10. 【emWin】例程十九:窗口对象——Checkbox

    简介: 复选框是选择各种不同选项的最常用小工具之一.用户可选中或取消选中复选框,并且可一次选中任意个框 触摸校准(上电可选择是否进入校准界面) CHECKBOX三状态模式 CHECKBOX设置字体颜色 ...