題目描述
分析
(1)由於0只是每次交換的一個基準,因此0所在的位置錯誤可以不計入總的錯誤數,因爲最終其他的數都排列好之後,0必然也在0號位。由於一次交換時0回到0號位而需要將錯誤數減少2,而不回到0號位只需要減1,這樣做是爲了避免分類。
(2)爲了方便找到每個數字所在的位置,可用v[i]
存放數字i
所在的位置。每次只需要對v[]
進行swap即可。
(3)當0回到0號位而並未完成工作時,需要找一個放在錯誤位置的數與0交換,所以可以事先存好錯誤的數。
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<stack>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
int v[100005];
unordered_set<int> sett;
int main() {
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
int n, cnt=0; cin >> n;
for (int i = 0; i < n; i++) {
int num; cin >> num;
v[num] = i;
if (num != 0 && num != i) sett.insert(num);
}
while (sett.size() > 0) {
if (v[0] == 0) {
swap(v[0], v[*sett.begin()]);
cnt++;
}
else {
sett.erase(v[0]); //注意先erase,因爲swap會改變v[0]的值
swap(v[v[0]], v[0]);
cnt++;
}
}
cout << cnt;
return 0;
}