【PTA数据结构 | C语言版】与零交换
将 { 0, 1, 2, …, n−1 } 的任意一个排列进行排序并不困难,这里加一点难度,要求你只能通过一系列的 Swap(0, *) —— 即将一个数字与 0 交换 —— 的操作,将初始序列增序排列。例如对于初始序列 { 4, 0, 2, 1, 3 },我们可以通过下列操作完成排序
·
本专栏持续输出数据结构题目集,欢迎订阅。
题目
将 { 0, 1, 2, …, n−1 } 的任意一个排列进行排序并不困难,这里加一点难度,要求你只能通过一系列的 Swap(0, *) —— 即将一个数字与 0 交换 —— 的操作,将初始序列增序排列。例如对于初始序列 { 4, 0, 2, 1, 3 },我们可以通过下列操作完成排序:
- 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 个非负整数的给定排列进行增序排序所需要的最少的与 0 交换的次数。
输入格式:
输入在第一行给出正整数 n (≤10^5);随后一行给出{ 0, 1, 2, …, n−1 } 的一个排列。数字间以空格分隔。
输出格式:
在一行中输出将给定序列进行增序排序所需要的最少的与 0 交换的次数。
输入样例:
10
3 5 7 2 6 4 9 0 8 1
输出样例:
9
代码
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
scanf("%d", &n);
int *arr = (int *)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
int *visited = (int *)calloc(n, sizeof(int)); // 标记元素是否已处理
int total_swaps = 0;
for (int i = 0; i < n; i++) {
if (!visited[i] && arr[i] != i) { // 找到未处理的循环
int cycle_len = 0;
int current = i;
int has_zero = 0; // 标记循环中是否包含0
// 遍历当前循环
while (!visited[current]) {
visited[current] = 1;
cycle_len++;
if (arr[current] == 0) {
has_zero = 1;
}
current = arr[current]; // 移动到下一个元素
}
// 根据循环是否包含0计算交换次数
if (has_zero) {
total_swaps += (cycle_len - 1);
} else {
total_swaps += (cycle_len + 1);
}
}
}
printf("%d\n", total_swaps);
return 0;
}

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)