<OJ_Sicily>Inversion Number

来源:互联网 发布:java double api 编辑:程序博客网 时间:2024/06/10 19:39

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


0 0