这个题就是求1-n的一个排列,最少交换多少次能变成递增排列
看过置换的都知道任何一个排列都能表示成几个循环的乘积
那么我们这里找出每个循环,记录每个循环有几个元素
在一个循环里最少的交换次数就是元素个数减一
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
const int N=200000+5;
int a[N],vis[N];
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int ans=0;
for(int u=1;u<=n;u++)
{
int v=a[u];
int num=0;
while(u!=v && !vis[u])
{
vis[u]=1;
num++;
u=v;
v=a[u];
}
if(num!=0) ans+=num-1;
}
printf("%d\n",ans);
}
return 0;
}