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;
}