题意:给定一排列 [ 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); }代码很简单,关键是贪心的思路。
