#include <iostream>
using namespace std;
int a[100005],position[100005],N,inPositionNum=0,count=0,SwapTo=0;
int FindFirst(int begin)
{
for(int i=begin;i<N;i++)
if(a[i]!=i)
return i;
return -1;
}
int main()
{
scanf("%d",&N);
for(int i=0;i<N;i++)
{
scanf("%d",&a[i]);
position[a[i]]=i;
}
while(FindFirst(SwapTo)!=-1)
{
if(a[0]==0)
{
SwapTo = FindFirst(SwapTo);
if(SwapTo == -1)
break;
a[0] = a[SwapTo];
a[SwapTo] = 0;
position[0] = SwapTo;
position[a[0]] = 0;
}
else
{
a[position[0]] = position[0];
a[position[position[0]]]=0;
int temp = position[0];
position[0] = position[temp];
position[temp] = temp;
}
count++;
}
printf("%d",count);
return 0;
}
输入:10 3 5 7 2 6 4 9 0 8 1
输出:9
一道模拟题,细节注意就能过,太久没做题,这题做了很久,也参考了网上的代码,但最终还是修改自己的第一份代码过的。
整体思路:手工操作一次就能明白模拟顺序是这样的,用数组a[]保存输入数据,即要被排序的序列,用数组position[]保存输入数据的下标,
如position[3]=0表示元素3在原始数组中的下标为0。
然后不断地去交换0和当时0所在位置应该填入的元素,直到0被换到下标为0的位置时,要进行一次废操作,即把0与一个位置摆放不对的元素进行交换。
整个循环结束的时机就是当原始数组中不存在a[i]!=i的情况。
一开始超时,后来看了别人的代码,对FindFirst函数进行了优化,就不超时了,不需要每一次都从0开始检测,这里还不是很明白,回头再看看。