7-16 Sort with Swap(0, i) | PTA数据结构与算法——C语言实现

2013年浙江大学免试研究生上机考试真题。

原题链接:PTA | 程序设计类实验辅助教学平台 

题目描述

        给定包含数字 {0, 1, 2,..., N−1} 的任一排列,很容易对它们进行升序排序。 但是如果只允许使用Swap(0, *) 操作呢? 例如,要对 {4, 0, 2, 1, 3} 进行排序,我们通过以下方式应用Swap操作达到排序的目的: 

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

        现在要求找到对 N 个非负整数的给定排列进行排序所需的最小交换次数。 

输入格式

        每个输入文件包含一个测试用例,第一行为一个正整数N (≤1E5),第二行为一个排列序列 {0, 1, ..., N−1}。 一行中的所有数字都用空格分隔。

输出格式

        对于每种情况,只需在一行中打印对给定排列进行排序所需的最小交换次数。

输入样例

10
3 5 7 2 6 4 9 0 8 1
 

输出样例

 9

题目分析

         浙大讲解视频:数据结构_浙江大学_中国大学MOOC(慕课)

        排序的结果就是使每个数字在其对应的索引上,即a[0] = 0,...,a[N-1] = N-1。核心点在于:N个数字的排列由若干个独立的环组成。在环内对元素进行交换即可使数据归位。

        一个包含n个数,且其中含0的环,需要n-1次Swap(0, *)使所有数字归位;对于一个包含n个数,且其中不含0的环,需要先进行一次Swap(0, *)使0入环,再进行(n+1)-1次Swap(0, *)使所有数据归位,合计共进行了n+1次交换;对于已经归位的单元素环,直接continue。

代码

        使用C语言实现。

#include <stdio.h>
#define MAXN 100000

int a[MAXN];

int SwapNum(int a[], int N);

int main() {
	int N;
	scanf("%d", &N);
	for (int i = 0; i < N; i++)
		scanf("%d", &a[i]);
	
	int re = SwapNum(a, N);
	printf("%d", re);

	return 0;
}

int SwapNum(int a[], int N) {
	int ans = 0, count = 0;
	int temp_idx;
	int contain_0 = 0;	// 环内是否包含0
	for (int i = 0; i < N; i++) {
		if (a[i] == i)    // 已经归位
			continue;

		while (a[i] != i) {
			if (a[i] == 0)
				contain_0 = 1;	// 环内包含0
			temp_idx = a[i];
			a[i] = i;
			i = temp_idx;
			count++;
		}
		if (contain_0)	// 包含0
			ans += (count - 1);
		else	// 不包含0
			ans += (count + 1);
		contain_0 = 0;
		count = 0;
	}
	return ans;
}

 测试结果

猜你喜欢

转载自blog.csdn.net/qq_40481602/article/details/126512084