10-排序6 Sort with Swap(0, i)
分数 25 作者 陈越 单位 浙江大学
Question:
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 1
Sample Output:
9
代码长度限制:16 KB 时间限制:400 ms 内存限制:64 MB
Answer:
示例推演:
发现与结论:
代码展示:
# include<stdio.h>
// 返回一个数组中大环的个数
int CycleNum(int Array[], int N);
int main(){
// 接收数组大小
int N;
scanf("%d",&N);
int Array[N];
// 接收元素并统计
int i,Position,SmallCount=0;
for(i=0;i<N;i++){
scanf("%d",&Array[i]);
if(Array[i]==0){
// 存储开始时0元素的位置
Position = i;
}
if(Array[i] == i){
// 统计一下自成环的个数,并将其位置标记为-1
Array[i] = -1;
SmallCount++;
}
}
// 检查一下0是否在位置0上(即是否自成环)
int valid = 0;
if(Position == 0)valid = 1;
// 统计一下这个数组中大环的个数(至少包含2个元素才能称为大环)
int BigCount = CycleNum(Array,N);
// 计算所有大环中元素的总个数
int BigNum = N - SmallCount;
// 计算最终交换次数
int Res = BigNum + BigCount;
if(valid==0)Res -= 2;
printf("%d",Res);
return 0;
}
// 统计一个数组有多少个大环
int CycleNum(int Array[], int N){
int i,j,tmp,Count = 0;
for(i=0;i<N;i++){
// 使用-1作为该位置元素已在某个环中的标志
if(Array[i]!=-1){
while(Array[i]!=-1){
tmp = i;
i = Array[i];
Array[tmp] = -1;
}
// 大环的数量加1
Count++;
}
}
return Count;
}