最小表示法——工艺

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值