题意:问能否通过交换A的逆序对把A序列变成B序列。
分析:属于是脑瘫觉得自己n次交换就够了。建了半天图对拍才发现做不了。因为大的只能往后移,考虑从大到小(从小到大也一样)枚举元素,对于第二个样例:
4 1 2 3 |
1 2 3 4 |
对于元素4:我们可以交换 1 2 3,这里我们直接交换3使得4对齐。
3 1 2 4 |
1 3 2 4 |
对于元素3:这里只能交换1。
这样我们就得到了一个能够通过所有样例的假做法。
事实上,第一次我们可以用4去依次交换 1 2 3,但这样A会变成1 2 3 4,后续无法操作。如果我们考虑依次交换最大的呢?这样我们又得到了一个能够通过所有样例的做法,事实上这是对的。
证明:对于 5 4 3 2 1,假设5要到最后去,如果我们直接交换 5 1,会得到 1 4 3 2 5;如果依次交换最大元素,会得到 4 3 2 1 5,后续4的选择会被最大化。
int a[maxn],b[maxn],pos1[maxn],pos2[maxn];
void solve()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],pos1[a[i]]=i;
for(int i=1;i<=n;i++) cin>>b[i],pos2[b[i]]=i;
vector<pii>ans;
for(int i=n;i>=1;i--)
{
for(int j=i-1;j>=1;j--)
{
if(pos1[j]>pos1[i]&&pos1[j]<=pos2[i])
{
ans.push_back({pos1[i],pos1[j]});
swap(a[pos1[i]],a[pos1[j]]);
swap(pos1[i],pos1[j]);
}
}
if(pos1[i]!=pos2[i])
{
cout<<-1<<endl;
return;
}
}
cout<<ans.size()<<endl;
for(auto x:ans) cout<<x.first<<" "<<x.second<<endl;
}