题目描述:皮划艇正在玩包含n个不同方块的益智游戏。他用从 1 到 n 的整数标记这些块,这些整数显示了块的原始位置。每次他可以交换两个方块,他想知道至少需要多少次才能恢复拼图。
注意重点:开一个标记数组,标记哪些位置已经解决。
#include <stdio.h>
#include <string.h>
const int maxn = 100100;
int a[maxn]; //输入数组
int b[maxn]; //标记数组
int main(void) {
int T;
scanf("%d", &T);
while(T--) {
memset(b, 0, sizeof(b)); //初始化
int n;
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d", &a[i]);
int ans = 0;
for(int i=1; i<=n; i++) {
int t = a[i]; //赋值正确的位置
int cnt = 0; //记录交换次数
while(b[t] == 0) {
//如果此处还没有解决
b[t] = 1; //标记此处已经解决
t = a[t]; //赋值正确的位置
cnt++; //交换次数 +1
}
if(cnt!=0) //若没有需要交换的则不需要更新
ans += cnt - 1; //因为是两两交换,所以需要 -1
}
printf("%d\n", ans);
}
return 0;
}