一开始看错题目,没看懂题目限制了每次交换必须用0与另一个数交换,求最小交换次数。一开始还以为是那种BIT线段数求逆序数组(冒泡排序次
数)那种题。
思路![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/419ad703fcb1ae01a9d75af13b5365f8.png)
代码
#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;
}