hdu 3374

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

HDOJ Monthly Contest – 2010.04.04

利用nxt数组很好推出循环次数,重点是最小最大表示法。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cstdio>
 5 const int N = 1000000 + 11;
 6 using namespace std;
 7 char ss[N],s[N<<1];
 8 int cs,n,a[N<<1],nxt[N];
 9
10 void pre()
11 {
12     nxt[1] = 0; int k = 0;
13     for(int i = 2; i <= n; ++i)
14     {
15         while(k > 0 && a[i] != a[k+1]) k = nxt[k];
16         if(a[i] == a[k+1]) ++k;
17         nxt[i] = k;
18     }
19 }
20
21 void Init()
22 {
23     n = strlen(ss);
24     strcpy(s,ss);
25     strcat(s,ss);
26     for(int i = 0; i < ( n << 1 ); ++i) a[i+1] = s[i];
27     pre();
28 }
29
30 int minx()
31 {
32
33     int i = 1,j = 2,k = 0;
34     while(i <= n && j <= n  && k < n)
35     {
36         if(a[i+k] == a[j+k] ) ++k;
37         else if(a[i+k] < a[j+k]) j = j + k + 1, k = 0;
38         else i = i + k + 1, k = 0;
39         if( i == j ) ++j;
40     }
41     return i;
42 }
43
44 void Solve()
45 {
46     cs = n - nxt[n];
47     if(n % cs == 0) cs = n/cs; else cs = 1; n = n/cs;
48     printf("%d %d ",minx(),cs);
49     for(int i = 1;i <= ( n << 1 ); ++i) a[i] = 0-a[i];
50     printf("%d %d",minx(),cs);
51 }
52
53
54 int main()
55 {
56     while(~scanf("%s",ss))
57     {
58         Init();
59         Solve();
60         puts("");
61     }
62     return 0;
63 }
时间: 2024-10-31 14:12:35

hdu 3374的相关文章

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.

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试了一个字符串的长度也没找到不同,则那个位置就是最小表示位置,

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

KMP,在有循环节的前提下: 循环节 t = len-next[len], 个数num = len/(len-next[len]); 个人理解,如果有循环节,循环节长度必定小于等于len/2, 换句话说next[len]>=len/2; 对于len%(len-next)!=0的这种情况不讨论,循环节不存在. 下面是假设循环节存在的情况 当次数等于2, 对于abcabc这种情况就不用说了,len = 6, next[len] = 3; 当次数大于2, 对于串a1 a2 a3 a4 a5 a6 a7

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 3374 String Problem (KMP+最大最小表示)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:输出最大最小表示是从哪一位开始,而且输出数量 http://acm.hdu.edu.cn/showproblem.php?pid=3374 数量好求,肯定是字符串的循环节,循环节可以直接通过KMP的Next数组得到.这个和yobobobo曾经研究过半天.. 对于最大最小表示法,就是将字符串不断旋转,得到字典序最大或者最小的.

hdu 3374 String Problem

String Problem http://acm.hdu.edu.cn/showproblem.php?pid=3374 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3153    Accepted Submission(s): 1272 Problem Description Give you a string with leng

HDU 3374(KMP+最小表示法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给出字符串,求最小表示法和最大表示法,并输出有几次出现,其实就是最小循环节的个数 题解:最小表示法求解,KMP求解最小循环节 最小循环节 = len - Next[len]  个数必须整出,如不整除,则为1. 代码如下: #include<iostream> #include<cstdio> #include<algorithm> #include<cst

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 3374 String Proble

String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3183    Accepted Submission(s): 1295 Problem Description Give you a string with length N, you can generate N strings by left shifts