1. 程式人生 > >浙大pat | 牛客網甲級 1025 Sort with Swap(0) (25)排序

浙大pat | 牛客網甲級 1025 Sort with Swap(0) (25)排序

題目描述

Given any permutation of the numbers {0, 1, 2,..., N-1}, it iseasy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed touse?  For example, to sort {4, 0, 2, 1,3} we may apply the swap operations in the following way:

Swap(0, 1) => {4, 1, 2, 0, 3}

Swap(0, 3) => {4, 1, 2, 3, 0}

Swap(0, 4) => {0, 1, 2, 3, 4}

Now you are asked to find the minimum number of swaps need to sort the givenpermutation of the first N nonnegative integers.

輸入描述:

Each input file contains one test case, which gives a positive N(<=105) followed by a permutation sequenceof {0, 1, ..., N-1}.  All the numbers ina line are separated by a space.

輸出描述:

For each case, simply print in a line the minimum number ofswaps need to sort the given permutation.

輸入例子:

10 3 5 7 2 6 4 9 0 8 1

輸出例子:

9

這一題使用了一種方法,就是檢查0的位置是否在0,如果不在0,就和應該在這個位置的數字交換位置,如果0在0,就和第一個不在其本身位置的數交換位置

這種方法的具體原理我還不清楚,不過貌似是使用的貪心演算法思想

這一題還有一點需要注意的就是,假如沒有找需要和0交換位置的數的時候都重新遍歷一遍陣列的話,那麼時間為O(n^2),這樣會超時嗎,所以需要維護一個numIndex陣列,numIndex[i]表示數字i在原陣列中的位置,然後維護一個index,index是第一個不在其本身位置上的數的位置,index左邊的數除了0以外全部都在其本身的位置上,

這樣每次將0和其他數交換位置的時候,同一時間也更新numIndex陣列,如果發現index位置的數是Index,那麼index右移,直到找到新的index,

這樣的話時間複雜度會非常大的降低

#include <iostream>
#include <algorithm>
using namespace std;

int num[100003];
int numIndex[100003];

void swapTheIndex(int indexOne,int indexTwo)
{
	swap(num[indexOne],num[indexTwo]);
	swap(numIndex[num[indexOne]],numIndex[num[indexTwo]]);
}

int main()
{
	int N;
	int indexOne,indexTwo;
	int index=1;
	int count=0;
	cin>>N;
	for(int i=0;i<N;i++)
	{
		cin>>num[i];
		numIndex[num[i]] = i;
	}
	while(index<N&&num[index] == index ) index ++;

	while(index<N)
	{
		if(numIndex[0] != 0 )
		{
			indexOne=numIndex[0];
			indexTwo = numIndex[numIndex[0]];
		    
			swapTheIndex(indexOne,indexTwo);
			count++;
			if(num[index] == index)
					while(index<N&&num[index] == index ) index ++;
		}
		else
		{
			indexOne = 0;
			indexTwo = index;
				swapTheIndex(indexOne,indexTwo);
				count++;
		}
	}

	cout<<count;
	return 0;
}