规定排序只能交换相邻元素,一般求排序交换的次数,即逆序数(用两个for求会超时,因为这样的题数据都会很大)
所以这里使用归并排序来计算逆序数
#include<stdio.h>
int a[500002]={0};
int b[500002]={0};
long long sum=0;
void memorgsort(int start,int mid,int end)
{
int i=start;
int j=mid+1;
int k=start;
int x;
while(i<=mid&&j<=end)//i...mid:a1<a2<a3<a4....
{ //j...end:b1<b2<b3....
if(a[i]<=a[j])
{
b[k++]=a[i++];
}
else{
sum+=j-k;//求逆序数
b[k++]=a[j++];
}
}
//有一组序列未被全部取出,接着取出来
while(i<=mid)
{
b[k++]=a[i++];
}
while(j<=end)
{
b[k++]=a[j++];
}
//将一组有序序列交给b
for(x=start;x<=end;++x)
{
a[x]=b[x];
}
}
void memorg(int low,int high)
{
int i;
if(low<high)
{
i=(low+high)/2;
memorg(low,i);//先将一堆数拆分
memorg(i+1,high);
memorgsort(low,i,high);//最后进行合并,可以看成两个有序序列进行合成,得到一个有序序列
}
}
int main()
{
int n,i,j;
while(~scanf("%d",&n))
{
sum=0;
if(n==0) break;
for(i=0;i<n;++i)
{
scanf("%d",&a[i]);
}
memorg(0,n-1);
printf("%lld\n",sum);
}
return 0;
}
所以这里有一个求逆序数的归并排序