Description
There is a permutation P with n integers from 1 to n. You have to calculate its inversion number, which is the number of pairs of Pi and Pj satisfying the following conditions: i<j and Pi>Pj.
Input
The input may contain several test cases.
In each test case, the first line contains a positive integer n (n<=100000) indicating the number of elements in P. The following n lines contain n integers making the permutation P.
Input is terminated by EOF.
Output
For each test case, output a line containing the inversion number.
题目解释:对于一个无序数组,求解逆序对的个数
解题思路:虽然说使用2个for循环就能够解决这个问题,但是使用for循环会导致超时。因此采用分治算法,将求解一个大数组的逆序数变成求解若干个小数组的逆序数。这个算法跟之前的最近邻点对的求解很类似。解题步骤如下:
(1)使用递归方式不断划分数组,直到不能再分
(2)对于相邻两个数组求解逆序数
(3)对求解完逆序数的两数组进行排序合并
(4)对于合并后的数组进行同样的操作。
后记:本来是想使用new和delete进行动态内存分配的,但是不能通过Sicily,不知道为何~
#include <iostream>
#include <stdio.h>
using namespace std;
int P[100005];
int element_num;
long long result; // 输出结果的类型一定要是long long型,否则会出错。
int getIndex(int *arr, int begin, int end, int target){
int mid = 0;
while (begin <= end) {
mid = (begin + end) /2;
if (target < arr[mid]) end = mid - 1;
else if(target > arr[mid]) begin = mid + 1;
else return mid;
}
return begin;
}
void sortmerge(int *arr, int begin, int mid, int end){
int i, j;
int l1 = mid - begin + 1;
int l2 = end - mid;
int *L = (int*)malloc(sizeof(int)*l1); // 动态创建数组存储左边数据
int *R = (int*)malloc(sizeof(int)*l2); // 动态创建数组存储右边数据
for (i = 0; i < l1; i++) {
L[i] = arr[i+begin];
}
for (i = 0; i < l2; i++) {
R[i] = arr[mid+1+i];
}
for(i = 0; i < l2; i++){
result += (l1 - getIndex(L, 0, l1-1, R[i]));
}
i = j = 0;
int k = begin;
while (i < l1 && j < l2) { // 对于两部分的数据进行排序
if (L[i] < R[j]) {
arr[k] = L[i];
i++;
}
else{
arr[k] = R[j];
j++;
}
k++;
}
while (i < l1) {
arr[k] = L[i];
k++;
i++;
}
while (j < l2) {
arr[k] = R[j];
k++;
j++;
}
free(L);
free(R);
}
void Merge(int *arr, int begin, int end){
if (begin < end) {
int mid = (begin + end) / 2;
Merge(arr, begin, mid);
Merge(arr, mid + 1, end);
sortmerge(arr, begin, mid, end);
}
}
int main(){
while (cin >> element_num) {
for (int i = 0; i < element_num; i++) {
cin >> P[i];
}
result = 0;
Merge(P, 0, element_num-1);
cout << result << endl;
}
return 0;
}