hdu 3374 String Problem (字符串的最小/大表示法+kmp)
hdu 3374 题目链接 题意:给出一个循环字符串,问最小表示出现的位置以及次数,最大表示出现的位置以及次数。 思路:之前只写过最小表示。。最大表示其实是一样的。。。把不等式方向变号即可。。。对于出现的次数。。。其实就等同于这个字符串是由几个子串组成。。。跑一遍kmp。。答案为len-nxt[len],1A
1/* ***********************************************
2Author :111qqz
3Created Time :2016年08月13日 星期六 03时22分47秒
4File Name :code/hdu/3374.cpp
5************************************************ */
6#include <cstdio>
7#include <cstring>
8#include <iostream>
9#include <algorithm>
10#include <vector>
11#include <queue>
12#include <stack>
13#include <set>
14#include <map>
15#include <string>
16#include <cmath>
17#include <cstdlib>
18#include <deque>
19#include <ctime>
20#define fst first
21#define sec second
22#define lson l,m,rt<<1
23#define rson m+1,r,rt<<1|1
24#define ms(a,x) memset(a,x,sizeof(a))
25typedef long long LL;
26#define pi pair < int ,int >
27#define MP make_pair
28using namespace std;
29const double eps = 1E-8;
30const int dx4[4]={1,0,0,-1};
31const int dy4[4]={0,-1,1,0};
32const int inf = 0x3f3f3f3f;
33const int N=1E6+7;
34char s[N],tmp[N];
35int minRep(char *s)
36{
37 int n = strlen(s);
38 int i = 0;
39 int j = 1;
40 int k = 0;
41 while (i<n&&j<n&&k<n)
42 {
43 int t = s[(i+k)%n]-s[(j+k)%n];
44 if (t==0) k++;
45 else
46 {
47 if (t>0)
48 i+=k+1;
49 else j +=k+1;
50 if (i==j) j++;
51 k = 0 ;
52 }
53 }
54 return i<j?i:j;
55}
56int maxRep(char *s)
57{
58 int n = strlen(s);
59 int i = 0 ;
60 int j = 1 ;
61 int k = 0 ;
62 while (i<n&&j<n&&k<n)
63 {
64 int t = s[(i+k)%n]-s[(j+k)%n];
65 if (t==0) k++;
66 else
67 {
68 if (t<0)
69 i+=k+1;
70 else j+=k+1;
71 if (i==j) j++;
72 k = 0 ;
73 }
74 }
75 return i<j?i:j;
76}
77int nxt[N];
78void getnxt(char *s)
79{
80 int n = strlen(s);
81 int i = 0 ;
82 int j = -1;
83 nxt[0] = -1;
84 while (i<n)
85 if (j==-1||s[i]==s[j]) nxt[++i]=++j;
86 else j = nxt[j];
87}
88int main()
89{
90 #ifndef ONLINE_JUDGE
91 freopen("code/in.txt","r",stdin);
92 #endif
93 while (scanf("%s",s)!=EOF)
94 {
95 int len = strlen(s);
96 int k = minRep(s);
97 int cnt = 0;
98 ms(tmp,0);
99 for ( int i = k ; cnt < len ; i++,cnt++)
100 tmp[cnt] = s[i%len];
101 getnxt(tmp);
102 printf("%d %d ",k+1,len/(len-nxt[len]));
103 k = maxRep(s);
104 cnt = 0 ;
105 ms(tmp,0);
106 for ( int i = k ; cnt < len ; i++,cnt++)
107 tmp[cnt] = s[i%len];
108 getnxt(tmp);
109 printf("%d %d\n",k+1,len/(len-nxt[len]));
110 }
111 #ifndef ONLINE_JUDGE
112 fclose(stdin);
113 #endif
114 return 0;
115}