https://codeforces.com/group/5yyKg9gx7m/contest/280318/problem/H
题意:给定n的排列,A和B,求A的最少相邻交换次数,使得A和B每个位置差的绝对值之和最大。
思路:
i
i
i对应
n
+
1
−
i
n+1-i
n+1−i是一种,另外,如果n是偶数,则
[
1
,
n
/
2
]
[1,n/2]
[1,n/2]和
[
n
/
2
+
1
,
n
]
[n/2+1,n]
[n/2+1,n]任意对应都行,若n为奇数,
n
/
2
+
1
n/2+1
n/2+1分到左右边都可以,取较小的。
移动次数的话,按坐标从左到右依次取差的绝对值之和即可。
O
(
n
)
O(n)
O(n)
#include<bits/stdc++.h>
using namespace std;
const int maxn=250000+100;
typedef pair<int,int> P;
typedef long long ll;
#define MP(a,b) make_pair(a,b)
int n,a[maxn],b[maxn];
int main()
{
// freopen("input.in","r",stdin);
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
if(!(n&1))
{
ll s=0;
vector<int> A,B;
for(int i=1;i<=n;i++)if(a[i]<=n/2)A.push_back(i);
for(int i=1;i<=n;i++)if(b[i]>n/2)B.push_back(i);
for(int i=0;i<A.size();i++)s+=abs(A[i]-B[i]);
cout<<s;
}
else
{
ll s1=0,s2=0;
vector<int> A,B;
for(int i=1;i<=n;i++)if(a[i]<=n/2)A.push_back(i);
for(int i=1;i<=n;i++)if(b[i]>n/2+1)B.push_back(i);
for(int i=0;i<A.size();i++)s1+=abs(A[i]-B[i]);
A.clear();B.clear();
for(int i=1;i<=n;i++)if(a[i]<=n/2+1)A.push_back(i);
for(int i=1;i<=n;i++)if(b[i]>n/2)B.push_back(i);
for(int i=0;i<A.size();i++)s2+=abs(A[i]-B[i]);
cout<<min(s1,s2);
}
return 0;
}