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 N (<=105) 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 1Sample Output:
9
分析:一開始看到這道題,感覺沒看懂,後來就想,不就是先將所有數放到一個數組,然後判斷這個數是不是對應着它的序號也就是數組的下標(我沒用數組,我更親睞於vector哈,不過喲一樣的)。沒錯,如果它們相同,說明這個數就不需要交換。當然這個題目不是這樣就結束了(我開始傻傻的就這樣寫了,還在疑惑怎麼回事呢)T_T...
我們還差了一個東西,那就是有這樣的情況:就是0被交換到了序號0的位置,但是序列還沒排好(開始就是忘了這個T_T),,
因此,這個題目我們只需要求出那些數與序號不相對的數的個數再加上0有幾次被換到0序號位置上,當然最後一次不算啦,這樣這道題就解完了。。。
源碼:
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int main()
{
int N;
scanf_s("%d", &N);
vector<int> vec;
for (int i = 0; i < N; i++){
int num=0;
scanf_s("%d", &num);
vec.push_back(num);
}
int count = 0; //計數器
int cnt = 0; //一個標示符,表示第一個不爲0的數的序號
for (int i = 1; i < N; i++){ //求出第一個cnt
if (vec[i] != i){
cnt = i;
break;
}
}
while (cnt != 0){
if (vec[0] == 0){
vec[0] = vec[cnt];
vec[cnt] = 0;
count++;
}
while (vec[0] != 0){ //只要vec[0],就一直交換
int t = vec[0];
vec[0] = vec[vec[0]];
vec[t] = t;
count++;
}
int j;
for (j = cnt; j < N; j++){
if (vec[j] != j){
cnt = j;
break;
}
}
if (j == N) //到了最後,那麼就已經排好序了
cnt = 0;
}
cout << count << endl;
return 0;
}