CUMTOJ数据结构实验内容1-2 problemD

1094 problem 最少的交换 C++ 归并排序

题目描述

现在给你一个由n个互不相同的整数组成的序列,现在要求你任意交换相邻的两个数字,使序列成为升序序列,请问最少的交换次数是多少?

输入

输入包含多组测试数据。每组输入第一行是一个正整数n(n<500000),表示序列的长度,当n=0时。
接下来的n行,每行一个整数a[i](0<=a[i]<=999999999),表示序列中第i个元素。

输出

对于每组输入,输出使得所给序列升序的最少交换次数。

样例输入

5
9
1
0
5
4
3
1
2
3
0

样例输出

6
0

程序如下

#include 

using namespace std;

const int maxn = 500010;
int a[maxn];
int aux[maxn];
long long sum;
int n;

void merge(int l, int mid, int r) 
{
    int i = l;//第一部分的排好序的 
    int end1 = mid;
    int j = mid+1;//第二部分的排好序的 
    int end2 = r;

    for (int t = l; t <= r; t++) 
        aux[t] = a[t];//将初始的数组a[]全部录入到aux[]中 
    for (int t = l; t <= r; t++)//从左往右遍历数组a[] 
    {
        if (j > end2)//第二部分排好序的遍历完成,直接记录剩余的第一部分排好序的,移动次数不增加 
            a[t] = aux[i++];
        else if (i > end1)//第一部分排好序的遍历完成,直接记录剩余的第二部分排好序的,移动次数不增加  
            a[t] = aux[j++];
        else if (aux[i] > aux[j])//第一部分排好序的第一个元素>第二部分排好序的第一个元素 
        {
            sum += mid+1-i;//移动的元素为a[j]到a[i](即aux[i])的位置,次数为j-i(即mid+1-i) 
            a[t] = aux[j++];
        } 
        else if (aux[i] <= aux[j])//第一部分排好序的第一个元素<=第二部分排好序的第一个元素 
            a[t] = aux[i++];//记录到a[]中,i++,变为第一部分排好序的第二个元素 
    }
}

void msort(int l, int r) 
{
    if (l < r) 
    {
        int mid = (l + r)  / 2;
        msort(l, mid);
        msort(mid+1, r);
        merge(l, mid, r);
    }
}

int main(void) 
{
    while (cin >> n && n) 
    {
        sum = 0;
        for (int i = 0; i < n; i++) 
            cin >> a[i];
        msort(0, n-1);
        cout << sum << endl;
    }
    return 0;
}

你可能感兴趣的:(CUMTOJ数据结构实验内容1-2 problemD)