1. 程式人生 > >[排列組合]Codeforces Round #324 (Div. 2)E

[排列組合]Codeforces Round #324 (Div. 2)E

題意:
給出兩個序列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]); }