题目描述
给定一个数列{an},这个数列满足ai≠aj(i≠j),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换?
输入输出格式
输入格式:
第一行,正整数n (n<=100,000)。
以下若干行,一共n个数,用空格分隔开,表示数列{an},任意-231<ai<231。
输出格式:
只有一行,包含一个数,表示最少的交换次数。
输入输出样例
输入样例#1:
8 8 23 4 16 77 -5 53 100
输出样例#1:
5 ---------------------------------------------------------------------------------------------------------------本以为是逆序对,发现不一定相邻交换找一条交换链,从原位置到新位置不停地走,最终会是一个环注意每次加cnt-1,因为最后一次两个都到了正确位置代码实现原位置封装结构体,排序,flag代表归位,走就行了
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N=100005; struct node{ int o,w; }a[N]; bool cmp(const node &a,const node &b){ return a.w<b.w; } int n,flag[N],ans=0; //guiwei int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i].w); a[i].o=i; } sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++){ if(flag[i]==0){ int now=i,cnt=0; while(flag[now]==0){ cnt++; flag[now]=1; now=a[now].o; } ans+=cnt-1; } } cout<<ans; }
时间: 2024-10-25 16:40:24