火柴排队

火柴排队

涵涵有两盒火柴,每盒装有 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;
}

猜你喜欢

转载自blog.csdn.net/beautiful_cxw/article/details/80970473