题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如,有一个数组为Array[0..n] 其中有元素a[i],a[j].如果 当i<j时,a[i]>a[j],那么我们就称(a[i],a[j])为一个逆序对。在数组{7,5,6,4}中一共存在5对逆序对,分别是(7,6),(7,5),(7,4),(6,4),(5,4)。
归并排序O(n*logn)
题目1384:数组中的逆序对 http://ac.jobdu.com/problem.php?pid=1348
#include<iostream>
#include<stdlib.h>
#include<cstdio>
using namespace std;
const int maxn = 100001;
void printArray(int arry[],int len)
{
for(int i=0;i<len;i++)
cout<<arry[i]<<" ";
cout<<endl;
}
int MergeArray(int arry[],int start,int mid,int end,int temp[])//数组的归并操作
{
//int leftLen=mid-start+1;//arry[start...mid]左半段长度
//int rightLlen=end-mid;//arry[mid+1...end]右半段长度
int i=mid;
int j=end;
int k=0;//临时数组末尾坐标
int count=0;
//设定两个指针ij分别指向两段有序数组的头元素,将小的那一个放入到临时数组中去。
while(i>=start&&j>mid)
{
if(arry[i]>arry[j])
{
temp[k++]=arry[i--];//从临时数组的最后一个位置开始排序
count+=j-mid;//因为arry[mid+1...j...end]是有序的,如果arry[i]>arry[j],那么也大于arry[j]之前的元素,从a[mid+1...j]一共有j-(mid+1)+1=j-mid
}
else
{
temp[k++]=arry[j--];
}
}
//cout<<"调用MergeArray时的count:"<<count<<endl;
while(i>=start)//表示前半段数组中还有元素未放入临时数组
{
temp[k++]=arry[i--];
}
while(j>mid)
{
temp[k++]=arry[j--];
}
//将临时数组中的元素写回到原数组当中去。
for(i=0;i<k;i++)
arry[end-i]=temp[i];
//printArray(arry,8);//输出进过一次归并以后的数组,用于理解整体过程
return count;
}
//注意:inversions不能声明为int型,必须为long long型。
//因为题目中说数组最大为10^5,那么最大逆序对为(10^5-1)*10^5/2,这个数大约在50亿左右,超过了int型的表示范围。
long long InversePairsCore(int arry[],int start,int end,int temp[])
{
long long inversions = 0;
if(start<end)
{
int mid=(start+end)/2;
inversions+=InversePairsCore(arry,start,mid,temp);//找左半段的逆序对数目
inversions+=InversePairsCore(arry,mid+1,end,temp);//找右半段的逆序对数目
inversions+=MergeArray(arry,start,mid,end,temp);//在找完左右半段逆序对以后两段数组有序,然后找两段之间的逆序对。最小的逆序段只有一个元素。
}
return inversions;
}
long long InversePairs(int arry[],int len)
{
int *temp=new int[len];
long long count=InversePairsCore(arry,0,len-1,temp);
delete[] temp;
return count;
}
int a[maxn];
int main()
{
int n;
while (scanf("%d",&n) == 1)
{
for (int i = 0; i < n; i++)
scanf("%d",&a[i]);
long long count = InversePairs(a,n);
printf("%lld\n",count);
}
return 0;
}
参考: http://www.cnblogs.com/xwdreamer/archive/2012/10/12/2721938.html
763

被折叠的 条评论
为什么被折叠?



