这道E题真的毒瘤啊,看完题解后还花了三小时AC。。。
主要是让这个位置上的数字如果要换到前面,那么前面至少有一个要到这个位置上,交换就好啦。
交换之后更新位置,直到这个数字被交换到指定位置。
为了 简化操作,我们可以把所有目标序列(s列)中数字出现的位置替换p序列中的数字,这样目标序列转化成一个1到n的序列
#include<bits/stdc++.h> using namespace std; int p[2001]; int s[2001]; int pos[2001]; int tot; int res=0; struct oper{ int i; int j; }op[2000001]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&p[i]); } for(int i=1;i<=n;i++) { scanf("%d",&s[i]); pos[s[i]]=i; } for(int i=1;i<=n;i++) { if(pos[p[i]]<i) res+=(i-pos[p[i]]); } printf("%d\n",res); for(int i=1;i<=n;i++) { p[i]=pos[p[i]]; } for(int i=1;i<=n;i++)//从头开始找,找到p[i]<i, { if(p[i]<i)//找到之后从后向前遍历, 找到第一个p[j] >=i交换,更新i的位置,继续向前交换,直到p[i]==pos { int pos=i; while(pos>p[pos]) { for(int j=pos-1;j>=1;j--) { if(p[j]>=pos) { swap(p[j],p[pos]); op[++tot].i=pos; op[tot].j=j; pos=j; break; } } } } } printf("%d\n",tot); for(int i=1;i<=tot;i++) { printf("%d %d\n",op[i].i,op[i].j); } }