火柴排队
涵涵有两盒火柴,每盒装有 nn 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为\sum (a_i-b_i)^2∑(ai−bi ) ^2其中 a_ia i
表示第一列火柴中第 i i 个火柴的高度, b_ib i
表示第二列火柴中第 ii 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 99,999,997 取模的结果。
输入输出格式
输入格式:
共三行,第一行包含一个整数 nn ,表示每盒中火柴的数目。
第二行有 n n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 nn 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。
输出格式:
一个整数,表示最少交换次数对 99,999,99799,999,997 取模的结果。
题解:很容易得到,一定要是每个数组同序数位相对才会得到最小值,那么就先快排都置成升序,用一开始记录下的序号一一匹配,再用归并排序求逆序对。
那个结论证明的话其实也挺简单的,自己想想。
归并排序:
void mergearray(int a[], int first, int mid, int last, int temp[])
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
void mergesort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
mergesort(a, first, mid, temp); //左边有序
mergesort(a, mid + 1, last, temp); //右边有序
mergearray(a, first, mid, last, temp); //再将二个有序数列合并
}
}
bool MergeSort(int a[], int n)
{
int *p = new int[n];
if (p == NULL)
return false;
mergesort(a, 0, n - 1, p);
delete[] p;
return true;
}
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<cstdio>
using namespace std;
int k,n,m,q,tmp1[100001],e[100001];
long long ans;
struct node
{
int x,y;
}a[100001],b[100001];
void merge(int left, int mid, int right)
{
int i=left, j=mid+1, k=left;
while (i<=mid && j<=right) {
if (e[i]<=e[j]) {
tmp1[k++] = e[i++];
} else {
tmp1[k++] = e[j++];
ans = ans+mid-i+1;
}
}
while (i<=mid) tmp1[k++] = e[i++];
while (j<=right)tmp1[k++] =e[j++];
memcpy(&e[left], &tmp1[left], (right-left+1)*sizeof(int));
}
void merge_sort(int left, int right)
{
if (left < right)
{
int mid=(left+right)>>1;
merge_sort(left, mid);
merge_sort(mid+1, right);
merge(left, mid, right);
}
}
bool cmp(node x,node y)
{
return x.x<y.x;
}
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
cin>>n;
for (int i=1; i<=n; i++)
{
cin>>a[i].x;
a[i].y=i;
}
for (int i=1; i<=n; i++)
{
cin>>b[i].x;
b[i].y=i;
}
sort(a+1,a+n+1,cmp);
sort(b+1,b+n+1,cmp);
for (int i=1; i<=n; i++)
e[b[i].y]=a[i].y;
merge_sort(1,n);
cout<<ans%99999997;
}