实验任务
小菇凉和小光头在森林里找了许久都没有看到出路。小菇凉生气了,叫出了小熊提伯斯烧光了附近的树木。一只老鼠跳了出来!指责他们烧到了自己,打扰了自己计算很腻害的东西。小光头连忙道歉,可是老鼠还是很生气,要求他们帮它解决他在计算的那个难题才肯放他们过去。小光头只好帮忙解决老鼠的问题。
老鼠在解决的问题是这样的,有一串数字序列,老鼠想知道需要多少次相邻对换才能把这串数字序列变成递增上升的序列。
数据输入
输入包括多组数据,每组数据一个数字 n 表示序列共 n 个数。(n<=10000)接下来 n 个数 0 ≤ a[i] ≤ 999,999,999 表示这个序列。输入 n=0 时结束。
数据输出
输出最少经过几次相邻对换,可以使序列成为递增有序的。
输入示例
5
9 1 0 5 4
3
1 2 3
0
输出示例
6
0
解题思路
归并排序的简单应用
参考代码
#include <stdio.h>
const int maxn = 10010;
__int64 a[maxn],temp[maxn];
void MergeSort(int first,int last);
void Merge(int first,int mid,int last);
int cnt;
int main()
{
int n;
while (~scanf("%d",&n) && n){
for (int i = 0;i < n;i++)
scanf("%I64d",&a[i]);
cnt = 0;
MergeSort(0,n-1);
printf("%d\n",cnt);
}
return 0;
}
void MergeSort(int first,int last){
if (first < last){
int mid = (first + last)/2;
MergeSort(first,mid);
MergeSort(mid+1,last);
Merge(first,mid,last);
}
}
void Merge(int first,int mid,int last){
int i = first,j = mid + 1,k = 0;
int m = mid, n = last;
while (i <= m && j <= n){
if (a[i] <= a[j])
temp[k++] = a[i++];
else{
temp[k++] = a[j++];
cnt += (m+1-i); //关键步,如果a[j] > a[j]说明要交换,交换的次数就是a[i]到a[m]中元素的个数,即(m+1-i)
}
}
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];
}