标签: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;
}
标签:pair mat bre mes 表示 return end i+1 algorithm
原文地址:https://www.cnblogs.com/loney-s/p/13344197.html