Description
小敏和小燕是一对好朋友。
他们正在玩一种神奇的游戏,叫Minecraft。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。
Input
第一行两个整数n,代表方块的数目。
第二行n个整数,每个整数按从左到右的顺序输出方块瑕疵度的值。
Output
一行n个整数,代表最美观工艺品从左到右瑕疵度的值。
Sample Input
10
10 9 8 7 6 5 4 3 2 1
Sample Output
1 10 9 8 7 6 5 4 3 2
#include<iostream>
using namespace std;
const int maxn=300005;
int a[maxn],mz,n;
inline int solve(){
int i=0,j=1,k=0,t;
//本题因为不涉及到修改数据操作,只涉及到查询操作
//因而在寻找最小表示的时候
//利用两个位置指针和一个移动指针,模拟了两个数组
//用O(2n)的时间复杂度就能找到最小表示
//首先我们将数据组看做一个环,因为我们移动的操作就是在一个环上进行操作
//因为我们要找到最小表示,所以必须有比较的环节
//i和j分别为模拟的 环中的开始位置,他们两个相互比较,这样遍历一遍
//元素就能找到最小表示的开始,在按照环的形式输出就行
while(i<n&&j<n&&k<n)
{ //i,j模拟起始位置必须小于所有元素个数
//k表示的是移动的个数,也必须小于元素个数
t=a[(i+k)%n]-a[(j+k)%n];
//本公式有两个含义首先,i~i+k-1和j~j+k-1每一个元素都是一一对应的
//我们由t来判断i+k和j+k的关系
if(t==0)
k++;
//如果两个元素仍然相等,我们还是只将移动数加一,而起始位置不变
else
{
if(t>0)//如果i+k大于j+k那么以j的其实位置的表示是目前最小的表示
i=i+k+1;//且以i为起始位置的表示一定不是最小表示,将i指针移动到i+k+1位置
//然后将移动长度数为0,继续向下寻找最小表示
else j=j+k+1;
if(i==j)j++;//保持让两个指针模拟两个不同的起始位置
k=0;
}
}
return min(i,j);//较大的表示起始位置一定会移动到后面
}
int main(){
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
mz=solve();
cout<<a[mz]<<" ";
for(int i=(mz+1)%n;i!=mz;i=(i+1)%n)
{
cout<<a[i]<<" ";
}//以环的形式输出数据
return 0;
}