1067 Sort with Swap(0, i) (25分) (贪心)
题意:给定一排列 [ 0 , n ) [0,n) [0,n)和 s w a p ( 0 , i ) swap(0,i) swap(0,i)操作,问最少多少次操作使得数组成递增序。
思路:一个很显然的交换方法就是:假如我们想让数字 i i i到位置 i i i,我们先让 0 0 0与位置 i i i的数交换,然后 0 0 0再与数字 i i i交换即可。
但是这会多一次占位的操作,根据贪心,我们可以先让 0 0 0所占据的位置 p o s pos pos的数回归到 p o s pos pos,这样 0 0 0与 p o s pos pos交换只需要一次,所以我们应该先尽可能进行该种方法,然后再特判 i i i是否在位置 i i i上,如果不在就让 0 0 0先占位,这样下一次就少用一次占位操作了,可以直接交换了。
#include<iostream>
#include<cstdio>
#define pb push_back
using namespace std;
const int N=1e5+5;
int a[N];
int main(){
int n,s=0;
scanf("%d",&n);
for(int i=0,x;i<n;i++) scanf("%d",&x),a[x]=i;
for(int i=1;i<n;i++){
while(a[0]){
swap(a[0],a[a[0]]);
s++;
}
if(a[i]!=i) swap(a[0],a[i]),s++;
}
printf("%d\n",s);
}
代码很简单,关键是贪心的思路。