题目链接:https://cn.vjudge.net/problem/HDU-3743
题意:
给出一组 n 个数,每次交换相邻的两个整数,要你用最少的交换次数使得该排列呈递增排列。输出需要交换的次数。
分析:
这道题和 POJ 2299 Ultra-QuickSort 一模一样,都可以采用归并排序的方法,在排序中计数即可。归并排序的具体实现可以点击这里查看。
代码:
#include <cstdio>
using namespace std;
long long cnt = 0;
void MergeArray(int a[], int l, int mid, int r,int tmp[]){ //a[]为原数组,tmp[]为辅助数组
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r){
if(a[i] <= a[j]) tmp[k++] = a[i++];
else{
tmp[k++] = a[j++];
cnt += mid + 1 - i; //对逆序对数进行计数,画个图手动排一下就知道这里是什么意思
}
}
while(i <= mid) tmp[k++] = a[i++];
while(j <= r) tmp[k++] = a[j++];
for(int i = 0; i < k; i++)
a[l + i] = tmp[i];
}
void MergeSort(int a[], int l, int r, int tmp[]){
if(l >= r) return;
int mid = (l + r) / 2;
MergeSort(a, l, mid, tmp);
MergeSort(a, mid + 1, r, tmp);
MergeArray(a, l, mid, r, tmp);
}
int main()
{
int n;
while(scanf("%d", &n) != EOF && n){
int a[n], tmp[n+5];
cnt = 0;
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
MergeSort(a, 0, n-1, tmp);
printf("%lld\n", cnt);
}
return 0;
}