数列排序

原题链接:https://www.luogu.org/problemnew/show/1327

题意简述:似乎不需要?反正就是一串数列任意交换两个数排序。

第一眼还以为是树状数组/归并排序求逆序对的裸题,然后仔细读题后发现可以任意交换,于是就想到了离散化解法。

自己独立写的第一个离散化,记录一下。

基本上就是每碰到一个错位的数,就交换一次,用一个数组来记录以来每个值都存在哪个位置上。

 

#include<cstdio>
#include<algorithm>
using namespace std;
int n,ans,f[100005];
struct num
{
    int a,b;
}p[100005];
bool cmp(num x,num y)
{
    return x.a<y.a;
}
bool cmp2(num x,num y)
{
    return x.b<y.b;
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&p[i].a);
        p[i].b=i;
    }
    sort(p,p+n,cmp);
    for(int i=0;i<n;i++) p[i].a=i;
    sort(p,p+n,cmp2);
    for(int i=0;i<n;i++) f[p[i].a]=i;
    for(int i=0;i<n;i++)
    {
        if(p[i].a!=i&&p[f[i]].a!=p[i].a)
        {
            ans++;
            int t=p[i].a,x=f[t];
            p[i].a=p[f[i]].a;
            p[f[i]].a=t;
            f[t]=f[x];
            f[i]=i;
        }
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-01-18 14:55  Excim  阅读(505)  评论(0编辑  收藏  举报