bzoj 2176 最小表示

2176: Strange string

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 419  Solved: 174
[Submit][Status][Discuss]

Description

给定一个字符串S = {S1, S2, S3 … Sn}, 如果在串SS中, 子串T(|T| = n)为所有长度为n的SS的字串中最小的(字符串的比较), 则称T为”奇怪的字串”. 你的任务就是找出这个字符串.

Input

读入两行, 第一行为n, 第二行为字符串S.

Output

将”奇怪的字串” T输出输入样例

Sample Input

10
asdfasdfas

Sample Output

asasdfasdf

HINT

数据范围

对于100%的数据, 保证n≤10000000;

给定的字符串中的字符保证在#33 ~ #254之间.

 

题解:最小表示法。

 1 #pragma GCC optimize(2)
 2 #pragma G++ optimize(2)
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 
 9 #define N 10000007
10 using namespace std;
11 inline int read()
12 {
13     int x=0,f=1;char ch=getchar();
14     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
15     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 
19 int n;
20 unsigned char a[N*2];
21 
22 int solve()
23 {
24     int i=1,j=2;
25     while(i<=n&&j<=n)
26     {
27         int k=0;while(a[i+k]==a[j+k]&&k<=n-1)k++;
28         if(k==n)break;
29         else if (a[i+k]<a[j+k])j=max(i+1,j+k+1);
30         else i=max(j+1,i+k+1);
31     }
32     return min(i,j);
33 }
34 int main()
35 {
36     n=read();
37     scanf("%s",a+1);
38     for (int i=1;i<=n;i++)
39         a[i+n]=a[i];
40     int st=solve();
41     for (int i=st;i<=st+n-1;i++)
42         putchar(a[i]);
43 }
原文地址:https://www.cnblogs.com/fengzhiyuan/p/8486654.html