題目鏈接:https://pintia.cn/problem-sets/994805342720868352/problems/994805403651522560
題目大意:給定n個數的序列(0--n-1),每次執行swap(0, *)操作,意思是把某個數所在的位置跟0所在的位置交換,求最少的移動次數。
分析:設一個left表示除0以外,還有多少個數不在自己的位置上,如果0的位置爲0,那麼就隨便找一個不在自己位置上的數,與0交換;如果0不在位置0,那麼執行swap(pos[0], pos[pos[0]]),且left--。
值得注意的是,如果是第一種情況,那麼我們需要找一個不在自己位置上的數,所以可以從1按順序開始找,但這個下標初始化在循環的外面,因爲是按從小到大的順序來的,假設當前k==x,那麼1--x-1肯定已經回到自己的位置了,所以不用每次都從頭開始找。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int pos[N];
int main() {
int n, x, sum = 0;
scanf("%d", &n);
int left = n - 1;
for(int i = 0; i < n; i++) {
scanf("%d", &x);
pos[x] = i;
if(x == i && x != 0) left--;
}
int k = 1;
while(left > 0) {
if(pos[0] == 0) {
while(k < n) {
if(pos[k] != k) {
swap(pos[0], pos[k]);
sum++;
break;
}
k++;
}
}
while(pos[0] != 0) {
swap(pos[0], pos[pos[0]]);
sum++;
left--;
}
}
printf("%d\n", sum);
return 0;
}