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 <iostream>
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;
}
网友评论