超时代码:
//最开始想用冒泡排序来解题的,但是超时了,呜呜呜。。。
#include <iostream>
#include <stdio.h>
#define MAXN 50050
int arge[MAXN];
using namespace std;
int main(void)
{
int N;
int count = 0;
scanf("%d", &N);
for (int i = 0; i < N; i++)
scanf("%d", &arge[i]);
for (int i = 0; i < N; i++)
for (int j = i + 1; j < N; j++)
if (arge[i] > arge[j])
count++;//每交换一次就证明是一次逆序呀
printf("%d", count);
return 0;
}
AC代码:
//既然冒泡不好用,那就来归并吧,复杂度为nlogn
#include <iostream>
#include <stdio.h>
#define MAXN 50050
using namespace std;
int arge[MAXN];//归并需要两个数组
int temp[MAXN];
int coun = 0;
void Merge(int head, int mid, int tail)
{//此时的两边都是已经排好序的数组
int pb = 0;//临时下标
int p1 = head, p2 = mid + 1;//选两个开头
while (p1 <= mid && p2 <= tail)//只要有一个到头了就结束
{
if (arge[p1] < arge[p2])
temp[pb++] = arge[p1++];
else
{//这里的意思是,只要出现右边大于左边的情况就说明,左边的所有元素都是右边的逆序数
temp[pb++] = arge[p2++];
coun += mid - p1 + 1;//所以这里要加上
}
}
while (p1 <= mid)
temp[pb++] = arge[p1++];
while (p2 <= tail)//没到头的继续放在后面
temp[pb++] = arge[p2++];
for (int i = 0; i < tail - head + 1; i++)
arge[head + i] = temp[i];//拷贝回原数组
}
void Merge_Sort(int head, int tail)
{
if (head < tail)
{
int mid = head + (tail - head) / 2;//寻找中点
Merge_Sort(head, mid);
Merge_Sort(mid + 1, tail);//分割
Merge(head, mid, tail);//归并
}
}
int main(void)
{
int n;
while (scanf_s("%d", &n) != EOF)
{
for (int i = 0; i < n; i++)
scanf_s("%d", &arge[i]);
Merge_Sort(0, n - 1);
printf("%d", coun);
}
return 0;
}