队列最小修改

题目描述

   已知一个奇怪的队列,这个队列中有n个数,初始状态时,顺序是1,2,3,4,…n,是1-n按顺序排列。这个队列只支持一种操作,就是把队列中的第i号元素提前到队首(1<i<=n),如有4个元素,初始为1,2,3,4,可以将3提前到队首,得到3,1,2,4 。 现在给出一个经过若干次操作之后的序列,请你找出这个序列至少是由原序列操作了多少次得到的。

输入描述

   第一行是一个整数n(1<=n<=10^5),表示序列中数字的数量。 接下来一行有n个数,是1-n的一个全排列。数字之间用空格隔开。

输出描述

输出仅包含一个数字,表示至少操作了几次。

示例

输入:
5
5 2 1 3 4
输出:
2

解题思路

   队列中的元素只能提到最前面,问至少操作多少次能够将1,2,3,…n的排列变成如题的排列,反过来就是至少需要多少次才能将队列恢复成1,2,…n的排列,注意只能将队首的元素向后放置到任意位置。
   操作最少就是操作最少的元素,对于一个元素,如果它的后面有比它小的元素,那么这个元素必须要移动,否则就无法实现顺序。
   那么从队首元素开始寻找顺序序列,如果后一个元素大于前一个元素,继续向后,如果小于前一个元素,那么将这段顺序序列全部移动,并且以这个小的元素作为第一个元素开始一段新的顺序序列的查找,直到遍历完所有元素。

代码实现

#include <iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int cnt=0;
	int sum=0;
	int val;
	int minx=-1;
	for(int i=0;i<n;i++){
		cin>>val;
		if(val>minx)
			cnt++;
		else if(val<minx){
			sum+=cnt;
			cnt=1;
		}
		minx=val;
	}
	cout<<sum<<endl;
}

关于通过移动元素完成队列顺序性有一道类似的题目,参见另一篇文章排序次数

发布了16 篇原创文章 · 获赞 0 · 访问量 340

猜你喜欢

转载自blog.csdn.net/qq_41922018/article/details/104262862