一開始看錯題目,沒看懂題目限制了每次交換必須用0與另一個數交換,求最小交換次數。一開始還以爲是那種BIT線段數求逆序數組(冒泡排序次
數)那種題。
思路
代碼
#include <iostream>
#include<cstdio>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
map<int, int> match;
queue<int> values;
int main(){
int n, cnt = 0, step = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++){
int x;
scanf("%d", &x);
match[x] = i;
if(i != x){
cnt++;
values.push(x);
}
}
while(cnt > 0){
int loc_zero = match[0];
//0沒到0位置上
if(loc_zero != 0){
int wrong = loc_zero;//0錯誤在的位置就是要交換的值
cnt--;
//恰好0換到0的位置上去
if(match[wrong] == 0){
cnt--;
}
int tmp = match[wrong];//該值錯誤在的地方
match[wrong] = wrong;
match[0] = tmp;
}
//0到了0位置上,快速找到那個位置不對的傢伙交換位置
else{
int wrong;
while(!values.empty()){
int t = values.front();
values.pop();
if(match[t] != t){
wrong = t;
break;
}
}
int tmp = match[wrong];
match[wrong] = match[0];
match[0] = tmp;
cnt++;//0本來正確的位置,但是交換後,0的位置也錯誤了
}
step++;
}
printf("%d", step);
return 0;
}