788. 逆序对的数量
题目描述
给定一个长度为n的整数数列,请你计算数列中的逆序对的数量。逆序对的定义如下:对于数列的第i个和第j个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆序对;否则不是。
输入格式
第一行包含整数n,表示数列的长度。
第二行包含 n 个整数,表示整个数列。
输出格式
输出一个整数,表示逆序对的个数。
数据范围
1≤n≤100000
样例
输入样例:
6
2 3 4 5 6 1
输出样例:
5
难度:简单
时/空限制:1s / 64MB
总通过数:7592
总尝试数:18517
来源:模板题
程序
1.简单的暴力枚举
#include<cstdio>
using namespace std;
int a[100005];
int main()
{
int n,i;
long long sum=0;
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%d",&a[i]);
for(i=0;i<n;i++){
for(int j=i+1;j<n;j++)
if(a[i]>a[j])sum++;
}
printf("%ld\n",sum);
}
程序注释:这个暴力枚举程序会超时,适合初学者,对于“程序员”(码龄大于2年的同学)不建议采纳。
2.归并
#include<cstdio>
using namespace std;
int a[100005],c[100005];
int msort(int l,int r){
int mid,pos,i,j,k,msum=0;
if(l==r)return 0;
mid=l+r>>1;
msum+=msort(l,mid);
msum+=msort(mid+1,r);
i=l;
j=mid+1;
pos=l;
while(i<=mid&&j<=r){
if(a[i]<=a[j])c[pos]=a[i++];
else{
msum+=j-pos;
c[pos]=a[j++];
}
pos++;
}
if(i<=mid)for(k=i;k<=mid;k++)c[pos++]=a[k];
else for(k=j;k<=r;k++)c[k]=a[k];
for(k=l;k<=r;k++)a[k]=c[k];
return msum;
}
int main()
{
int n,i,sum;
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%d",&a[i]);
sum=msort(0,n-1);
printf("%ld\n",sum);
return 0;
}
程序注释:这是出题人出这道题的本质,让我们用归并去做,不过这个程序较难,在考试时可以先考虑暴力枚举骗一点分,再思考用归并的方法去做。
注意:大家看完后一定不要抄袭,此程序仅供参考,望各位大师指点我的错误。
大家不要忘记点赞😄