题目链接:http://poj.org/problem?id=2299
题目意思:给你一个离散的数列,然后要排序成有序的序列,但每次只能在相邻的两个之间交换,问你要交换的最小次数。
这是简单的归并排序题,
给出归并排序的模板:
void merge(int low, int mid, int high)
{
int i,j,k;
i=k=low;
j=mid+1;
while(i<=mid && j<=high)
{
if(num[i]<num[j])
tmp[k++]=num[i++];
else
tmp[k++]=num[j++];
}
while(i<=mid)
tmp[k++]=num[i++];
while(j<=high)
tmp[k++]=num[j++];
for(i=low; l<=high; ++i)
num[i]=tmp[i];
}
void mergeSort(int a, int b)
{
int mid;
if(a<b)
{
mid=(a+b)/2;
mergeSort(a, mid);
mergeSort(mid+1, b);
merge(a, mod, b);
}
}
下面给出该题的代码:
#include<cstdio>
const int maxn=500000+5;
int num[maxn];
int tmp[maxn];
long long sum;
void merge(int low, int mid, int high)
{
int i, j, k;
i=k=low;
j=mid+1;
while(i<=mid && j<=high)
{
if(num[i]<num[j])
tmp[k++]=num[i++];
else
{
sum+=j-k;
tmp[k++]=num[j++];
}
}
while(i<=mid)
tmp[k++]=num[i++];
while(j<=high)
tmp[k++]=num[j++];
for(i=low; i<=high; ++i)
num[i]=tmp[i];
}
void mergeSort(int a, int b)
{
int mid;
if(a<b)
{
mid=(a+b)/2;
mergeSort(a, mid);
mergeSort(mid+1, b);
merge(a, mid, b);
}
}
int main(void)
{
int N;
//freopen("a.txt", "r", stdin);
//freopen("b.txt", "w", stdout);
while(1==scanf("%d", &N) && N>0)
{
int i;
sum=0;
for(i=0; i<N; ++i)
scanf("%d", &num[i]);
mergeSort(0, N-1);
printf("%lld\n", sum);
}
return 0;
}