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;
}