A 工艺

时间限制 : - MS   空间限制 : - KB 
评测说明 : 1s,128m
问题描述

小敏和小燕是一对好朋友。

他们正在玩一种神奇的游戏,叫Minecraft。

他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。

他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。

两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。

输入格式

第一行两个整数n,代表方块的数目。
第二行n个整数,每个整数按从左到右的顺序输出方块瑕疵度的值。

输出格式

一行n个整数,代表最美观工艺品从左到右瑕疵度的值。

样例输入

10
10 9 8 7 6 5 4 3 2 1

样例输出

1 10 9 8 7 6 5 4 3 2

提示

【数据规模与约定】

对于20%的数据,n<=1000

对于40%的数据,n<=10000

对于100%的数据,n<=300000

【分析】
   根据题意,我们使前面的数尽可能的小,于是第一位就应该是最小的一位。由于我们是处理同一个字符串,所以当第一位一开始就是最小一位时,就是最漂亮的。所以只需处理原字符串的最小表示即可。
由于输入中有空格,所以我选用数组代替字符串。
【标程】
 
 1 #include<iostream>
 2 #define maxn 300003
 3 using namespace std;
 4 int Len, i, j, k;
 5 int S[maxn * 2];
 6 void ini() {
 7     scanf("%d", &Len);
 8     for (int q = 0; q < Len; ++ q)scanf("%d", &S[q]), S[q + Len] = S[q];
 9     i = 0;
10     j = 1;
11 }
12 int Ex_() {
13     while (i < Len && j < Len) {
14         for (k = 0; k < Len; ++ k)
15             if (S[i + k] != S[j + k])break;
16         if (k == Len)break;
17         if (S[i + k] > S[j + k])i += k + 1;
18         else if (S[i + k] < S[j + k])j += k + 1;
19         if (i == j)++ j;
20     }
21     return min(i, j);   // 返回最小的一位的位置
22 }
23 void solve() {
24     int St = Ex_();
25     printf("%d ", S[St]);   //最关键的两步,由于最小表示法的方法是环形操作,最后一位又会回到第一位,所以先输出第一位,后面for循环结束条件就巧妙的设为i!=St,解决死循环。
26     for (int i = St + 1; i != St; i = (i + 1) % Len)printf("%d ", S[i]);   // 取模很关键
27 }
28 int main() {
29     ini();
30     solve(); 
31     return 0;
32 }
原文地址:https://www.cnblogs.com/Limbo-To-Heaven/p/11338944.html