题目描述
涵涵有两盒火柴,每盒装有 nn 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: \sum (a_i-b_i)^2∑(ai−bi)2
其中 a_iai 表示第一列火柴中第 ii 个火柴的高度, b_ibi 表示第二列火柴中第 ii 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,99799,999,997 取模的结果。
输入输出格式
输入格式:
共三行,第一行包含一个整数 nn ,表示每盒中火柴的数目。
第二行有 nn 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 nn 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。
输出格式:
一个整数,表示最少交换次数对 99,999,99799,999,997 取模的结果。
输入输出样例
输入样例#1:
4 2 3 1 4 3 2 1 4
输出样例#1:
1
输入样例#2:
4 1 3 4 2 1 7 2 4
输出样例#2:
2
说明
【输入输出样例说明1】
最小距离是 00 ,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。
【输入输出样例说明2】
最小距离是 10 ,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第 2 列中后 2 根火柴的位置。
题解:
我们的目的是让ai - bi尽可能小,也就是说要a中的第k大减去b中的第k大
很容易想到a和b按高度从大到小排序,得到的这个序列一定是最优的
接下来求交换次数。说到“交换次数”很容易联想到逆序对,但是这里借助离散化的思想
我们想象把排好序的数组“还原”回去,就是说让所有的f(i)都等于i
在f序列中的逆序对个数就是我们的交换次数
然后用归并排序求出f的逆序对即为所求
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#define MAXA 100005
#define MOD 99999997
using namespace std;
typedef long long LL;
struct Rx {
int Height;
int Idx;
}a[MAXA],b[MAXA];
bool cmp(Rx a,Rx b) {
return a.Height < b.Height;
}
int n,Ans,f[MAXA],temp[MAXA];
void Merge_sort(int Left,int Right) {
if(Left >= Right)
return;
int Mid = (Left + Right) >> 1;
Merge_sort(Left,Mid);
Merge_sort(Mid + 1,Right);
int i = Left,j = Mid + 1,k = Left;
while(i <= Mid && j <= Right) {
if(f[i] > f[j]) {
temp[k++] = f[j++];
Ans = (Ans + Mid - i + 1) % MOD;
}
else temp[k++] = f[i++];
}
while(i <= Mid)
temp[k++] = f[i++];
while(j <= Right)
temp[k++] = f[j++];
for(int i=Left;i<=Right;i++)
f[i] = temp[i];
}
int main() {
//freopen("match.in","r",stdin);
//freopen("match.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i].Height);
a[i].Idx = i;
}
for(int i=1;i<=n;i++) {
scanf("%d",&b[i].Height);
b[i].Idx = i;
}
sort(a + 1,a + n + 1,cmp);
sort(b + 1,b + n + 1,cmp);
for(int i=1;i<=n;i++)
f[a[i].Idx] = b[i].Idx;
Merge_sort(1,n);
printf("%d",Ans % MOD);
}