题解:
裸的字符串最小表示。。。
可以戳这里:http://www.cnblogs.com/ACAC/archive/2010/05/23/1742349.html
这里说一下为什么a[i+k]>a[j+k]的时候可以让 i 跳到 i+k+1
也就是说i-i+k这一段不会有一个后缀成为最小表示的前缀,那我们只要构造出一个比它小的就可以了。
显然 如果我们取a[i+x]--a[i+k+1],我们总有a[j+x]--a[j+x+1]比它小,也就是在长度不及len的时候就不是最小了所以不可能是最小表示。
所以我们枚举起点看看它能够延伸多长始终都是同长度中最小的,当该长度为len的时候说明它就是最小表示。
还有最后为什么要返回min(i,j)
因为。。。挖坑待填。。。
代码:
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<map> #include<set> #include<queue> #include<string> #define inf 1000000000 #define maxn 300000+5 #define maxm 20000000+5 #define eps 1e-10 #define ll long long #define pa pair<int,int> #define for0(i,n) for(int i=0;i<=(n);i++) #define for1(i,n) for(int i=1;i<=(n);i++) #define for2(i,x,y) for(int i=(x);i<=(y);i++) #define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y;i;i=e[i].next) #define mod 1000000007 using namespace std; inline int read() { int x=,f=;char ch=getchar(); while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();} while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();} return x*f; }
int n,a[maxn]; int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); n=read();
for0(i,n-)a[i]=read();
int i=,j=,k=;
while(i<n&&j<n&&k<n)
{
int t=a[(i+k)%n]-a[(j+k)%n];
if(!t)k++;
else
{
k=;
if(t>)i+=k+;else j+=k+;
if(i==j)i++;
}
}
int ans=min(i,j);
printf("%d",a[ans%n]);
for1(i,n-)printf(" %d",a[(ans+i)%n]); return ; }
2882: 工艺
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 48 Solved: 24
[Submit][Status]
Description
小敏和小燕是一对好朋友。
他们正在玩一种神奇的游戏,叫Minecraft。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。
Input
第一行两个整数n,代表方块的数目。
第二行n个整数,每个整数按从左到右的顺序输出方块瑕疵度的值。
Output
一行n个整数,代表最美观工艺品从左到右瑕疵度的值。
Sample Input
10
10 9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
Sample Output
1 10 9 8 7 6 5 4 3 2
HINT
【数据规模与约定】
对于20%的数据,n<=1000
对于40%的数据,n<=10000
对于100%的数据,n<=300000