题意:
给出两个序列p和s,问从p变化到s移动的最小距离是多少。
输出最小距离,移动的次数和移动的点。
分析:
逻辑总是感觉很混乱,这里把s的序列重新标号,那么s就是1,2,3,。。n.也就是将p重新标号后的顺序变化成有序递增的序列。这样逻辑上稍微清楚些。然后就是贪心的思想,在将b[k]移动到b[k]的位置的时候所经过的大于b[k]的数都往后移。
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <fstream>
#include <math.h>
#include <iomanip>
#define read freopen("q.in","r",stdin)
using namespace std;
typedef long long LL;
#define inf 0x3fffffff
typedef pair<int, int> pii;
const int maxn = 2003;
int mp[maxn];
int b[maxn],p[maxn];
int x[maxn*100],y[maxn*100];
int n;
int main()
{
//read;
int i,j,k,a,cnt=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&p[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&a);
mp[a]=i;
}
for(i=1;i<=n;i++)b[i]=mp[p[i]];
int res=0;
for(i=1;i<=n;i++)
{
// cout<<"EEEE"<<endl;
for(k=i;;k++)if(b[k]==i)break; //找出i点应该填的数的位置
while(i!=k)
{
for(j=i;j<=k;j++)
{
if(b[j]>=k)
{
swap(b[j],b[k]);
x[cnt]=j;
y[cnt++]=k;
res+=k-j;
k=j; //交换后,k的位置改变,继续移动
}
}
}
}
printf("%d\n%d\n",res,cnt);
for(i=0;i<cnt;i++)printf("%d %d\n",x[i],y[i]);
}