码迷,mamicode.com
首页 > 其他好文 > 详细

习题:Inversion SwapSort(思维)

时间:2020-07-20 13:23:21      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:pair   mat   bre   mes   表示   return   end   i+1   algorithm   

题目

传送门

思路

比较巧妙的一道构造题

首先考虑排列的情况

因为是排列,所以每一个数位上的最终状态一定是固定的

\(b_i\)满足\(a_{b_i}=i\)

如果交换\(a_{b_i},a_{b_j}\),那么\(b_i,b_j\)一定也会被交换

再者,如果\(a\)有序,那么\(b\)一定也有序,反之亦然

考虑逆序对映射到\(b\)上会是什么情况

\(b_i<b_j,a_{b_i}>a_{b_j}\)

考虑到\(b\)数组的定义

\(a_{b_i}>a_{b_j}\Rightarrow i>j\)

即对于\(b\)数组,每一对满足\(\begin{cases}b_i<b_j\\i>j\end{cases}\)都需要被交换,此处\(i和j\)是等价的,所以也可以写成\(\begin{cases}b_i>b_j\\i<j\end{cases}\)

此处容易发现这就是逆序对的形式,同时,对于\(a\)的逆序对,\(b\)一定有一个唯一的与其对应

即我们将b进行一个冒泡排序即可

记录下需要交换的\(b_i,b_{i+1}\)

那么对于数列的情况也是一样的,用两个关键字来表示一个数即可

代码

#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define x first
#define y second
int n;
int b[1005];
pair<int,int> a[1005],c[1005];
map<int,int> tot;
vector<pair<int,int> > ans;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].x;
        a[i].y=++tot[a[i].x];
        c[i]=a[i];
    }
    sort(c+1,c+n+1);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(c[i]==a[j])
            {
                b[i]=j;
                break;
            }
        }
    }
    for(int i=n;i>=1;i--)
    {
        for(int j=1;j<i;j++)
        {
            if(b[j]>b[j+1])
            {
                swap(b[j],b[j+1]);
                ans.push_back(make_pair(b[j],b[j+1]));
            }   
        }
    }
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++)
        cout<<ans[i].x<<‘ ‘<<ans[i].y<<endl;
    return 0;  
}

习题:Inversion SwapSort(思维)

标签:pair   mat   bre   mes   表示   return   end   i+1   algorithm   

原文地址:https://www.cnblogs.com/loney-s/p/13344197.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!