String Problem hdu 3374 最小表示法加KMP的next数组

String Problem

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

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

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #include <string.h>
 5 #include <set>
 6 using namespace std;
 7 char s[1100000];
 8 int next[1100000];
 9 int get(char s[],int flag,int l)
10 {
11     int i,j,k,t;
12     i=k=0;
13     j=1;
14     while(i<l&&j<l&&k<l)
15     {
16          t=s[(i+k>=l?i+k-l:i+k)]-s[(j+k>=l?j+k-l:j+k)];
17         if(!t)k++;
18         else
19         {
20             if(!flag)
21             {
22                 if(t>0)i+=k+1;
23                 else j+=k+1;
24             }
25             else
26             {
27                 if(t<0)i+=k+1;
28                 else j+=k+1;
29             }
30             if(i==j)j++;
31             k=0;
32         }
33     }
34     return i;
35 }
36 void getsnext(char s[],int l)
37 {
38     int i=1,j=0;
39     next[0]=0;
40     while(i<l)
41     {
42         if(j==0||s[i]==s[j])
43         {
44             i++,j++;
45             next[i]=j;
46         }
47         else j=next[j];
48     }
49     next[l-1]++;
50 }
51 int main()
52 {
53     while(~scanf("%s",s))
54     {
55         int l=strlen(s);
56         int minaa=get(s,0,l);
57         int maxaa=get(s,1,l);
58         getsnext(s,l);
59         cout<<minaa+1<<" "<<((l%(l-next[l-1]))?1:l/(l-next[l-1]));
60         cout<<" "<<maxaa+1<<" ";
61         cout<<((l%(l-next[l-1]))?1:l/(l-next[l-1]))<<endl;
62     }
63 }

String Problem hdu 3374 最小表示法加KMP的next数组,布布扣,bubuko.com

时间: 2024-12-15 01:36:55

String Problem hdu 3374 最小表示法加KMP的next数组的相关文章

String Problem - HDU 3374 (kmp+最大最小表示)

题目大意:有一个字符串长度为N的字符串,这个字符串可以扩展出N个字符串,并且按照顺序编号,比如串  ” SKYLONG “ SKYLONG 1 KYLONGS 2 YLONGSK 3 LONGSKY 4 ONGSKYL 5 NGSKYLO 6 GSKYLON 7 下面这7个都是原串的扩展(循环位移),现在需要求出来字典序最小的和字典序最大的那个串的标号.   输出说明:最小字典序的编号,最小字典序个数,最大字典序编号,最大字典序个数.   分析:以前也遇到过类似的求最小字典序的问题,不过当时不会

HDU 3374 最小/大表示法+KMP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给定一个串s,该串有strlen(s)个循环同构串,要求输出字典序最小的同构串的下标,字典序最小的出现次数,最大的同构串的下标,字典中最大的出现次数. 思路:对于求循环同构的字典序最小可以用最小表示法求得,最大也是一样.然后设ds为字符串s+s.然后就可以用KMP求最小串在ds出现的次数和最大串出现的次数了. #define _CRT_SECURE_NO_DEPRECATE #inclu

HDU 2609 最小表示法

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609 题意:给定n个循环链[串],问有多少个本质不同的链[串](如果一个循环链可以通过找一个起点使得和其他串相同,那么就认为这2个链是一样的.就是求不同构的串) 思路:对于求同构串可以用最小表示法,然后判断是否相等就可以知道这2个是否是同构了.判重用的是set #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdi

HDU 4162 最小表示法

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4162 题意:给定一个只有0-7数字组成的串.现在要由原串构造出一个新串,新串的构造方法:相邻2个位置的数字的差值.若为负数则要加上8,问新构造出来的串的一个字典序最小同构串是什么? 思路:就按照题意构造出新串后,然后就是最小表示法了. #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include&

最小表示法,以及二维数组的比较方法

雪花雪花雪花 用到的是最小表示法 有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,-,ai,6. 因为雪花的形状是封闭的环形,所以从任何一个角开始顺时针或逆时针往后记录长度,得到的六元组都代表形状相同的雪花. 例如ai,1,ai,2,-,ai,6和ai,2,ai,3,-,ai,6,ai,1就是形状相同的雪花. ai,1,ai,2,-,ai,6和ai,6,ai,5,-,ai,1也是形状相同的雪花. 我们称两片雪花形状相同,当且

HDU 3374 String 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 a

hdu 5284 wyh2000 and a string problem(没有算法,只考思维,字符数组得开20万,不然太小了)

代码: #include<cstdio> #include<cstring> using namespace std; char s[200000]; int main() { int t; scanf("%d",&t); while(t--) { scanf("%s",s); int w=0,y=0,h=0; int len=strlen(s); for(int i=0; i<len; i++) { if(w==0&&

hdu3374 kmp+最小表示法

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 lexic

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小表示的方法: (1)  利用两个指针p1, p2.初始化时p1指向s[0], p2指向s[1]. (2)  k = 0开始,检验s[p1+k] 与 s[p2+k] 对应的字符是否相等,如果相等则k++,一直下去,直到找到第一个不同,(若k试了一个字符串的长度也没找到不同,则那个位置就是最小表示位置,