bzoj 2176 最小表示
2176: Strange string
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 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
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 }