数列排序——模拟

给定一个数列 a,这个数列满足ai != aj(i != j),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换?

输入
第一行是一个整数,代表数字个数n(1 ≤ n ≤ 1e5).
第二行有n个整数用空格分隔开,表示数列a(−2e31< ai <2e31−1).

输出
只有一行,包含一个数,表示最少的交换次数。

Input
8
8 23 4 16 77 -5 53 100
Output
5
解析:
快排后的位置应该是每个数的最终位置,也就是说如果一个数移动到相应的位置后,就不用动了,这样的交换应该就是交换次数最少的。
如样例产生的效果:
8 23 4 16 77 -5 53 100
-5 23 4 16 77 8 53 100
-5 4 23 16 77 8 53 100
-5 4 8 16 77 23 53 100
-5 4 8 16 77 23 53 100
-5 4 8 16 23 77 53 100
-5 4 8 16 23 53 77 100
-5 4 8 16 23 53 77 100
-5 4 8 16 23 53 77 100

#include 
using namespace std;
#define int long long
#define endl '\n'
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int gcd(int a,int b) { return b? gcd(b,a%b) : a; }
typedef pair PII;
const double PI=acos(-1.0);
const int N=2e6+10;
struct node
{
    int x,id;
}str[N];
bool cmp(node a,node b)
{
    return a.x>n;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        str[i]={a[i],i};
    }
    sort (str+1,str+n+1,cmp);
    int ans=0;
    for (int i=1;i<=n;i++)
    {
        if (a[i]!=str[i].x)
        {
            ans++;
            int t=a[i];
            swap(a[i],a[str[i].id]);        //交换两个数的位置
            int l=i+1,r=n;
            while (l>1;
                if (str[mid].x>=t) r=mid;
                else l=mid+1;
            }
            str[l].id=str[i].id;            //相应的更新数a[i]的位置,由原来的str[l].id变成了str[i].id
        }
    }
    cout<>T;
    while (T--) solve(); 
    return 0;
}

你可能感兴趣的:(算法,数据结构)