题目
Given any permutation of the numbers {0, 1, 2,…, N−1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? 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 given permutation of the first N nonnegative integers.
Input Specification:
Each input file contains one test case, which gives a positive
followed by a permutation sequence of {0, 1, …, N−1}. All the numbers in a line are separated by a space.
Output Specification:
For each case, simply print in a line the minimum number of swaps need to sort the given permutation.
Sample Input:
10
3 5 7 2 6 4 9 0 8 1
Sample Output:
9
解题思路
题目大意: 给你一个乱序的序列(permutation ),从0到N-1,顺序打乱。下面给你一种交换排序的算法:每次交换只能和元素0进行交换,交换一定次数之后,达到升序。请问最小的交换次数。
解题思路: 题目限定只能和0元素交换,且要达到最小交换次数。所谓最小交换次数,我们务必保证每一次交换都是最有效率的,如何才算是最有效率呢?一次交换确定一个元素的最终位置。
因为每次交换都要用到0元素,不妨把0元素作为一个运载体,每交换一次,0元素把一个元素送到最终位置。
那么不妨考虑从0到N-1开始遍历,每次考察第i个元素是否在自己位置上,如果在,则跳过,如果不在,则用0元素与其交换;
交换之前,考察0元素所指向的位置,如果0元素不在0号位置上,那么先把占用0号位置的其他元素送回到自己该处的位置;
0号元素已经回归到自己的位置上时,再送第i号元素回第i号位置;
由于每次都要用到0号元素和0号位置,所以遍历可以从1开始,而不是0.
/*
** @Brief:No.1067 of PAT advanced level.
** @Author:Jason.Lee
** @Date:2019-01-07
** @Solution: Accepted!
*/
#include<iostream>
using namespace std;
int number[100010];
int main(){
int N;
while(cin>>N){
int input,swapTimes = 0;
for(int i=0;i<N;i++){
cin>>input;
number[input] = i;
}
for(int i=0;i<N;i++){
if(number[i]!=i){
while(number[0]!=0){
swap(number[0],number[number[0]]);
swapTimes++;
}
}
if(number[i]!=i){
swap(number[0],number[i]);
swapTimes++;
}
}
cout<<swapTimes<<endl;
}
return 0;
}
总结
都说这道题是基于贪心策略的,但是我却没有发现哪一点体现贪心思想了,可能是我对贪心的理解不够深吧。