Poj-2299 [用归并排序求逆序数的个数]

来源:互联网 发布:猎场删减 知乎 编辑:程序博客网 时间:2024/05/21 07:11

归并排序

具体可见《算法导论》——分治法。下例为POJ上2299题,用的是归并法求逆序数的个数:

/**    题目的意思就是要求冒泡排序的交换次数。    所用的算法:用归并排序,求逆序数的个数。    ##这道题充分印证了,即使merge本身可能用的不多,但分冶的思想却是无所不在**/#include <stdio.h>int left[250003], right[250003];long long count;void merge(int* a, int p, int q, int r){    int i, j, k, n1, n2;    n1 = q-p+1;    n2 = r-q;    for (i=0; i<n1; i++)    {        left[i] = a[p+i];    }    for (i=0; i<n2; i++)    {        right[i] = a[q+i+1];    }    left[n1] = right[n2] = 0x7fffffff;    i = j = 0;    for (k=p; k<=r; k++)    {        if (left[i] <= right[j])        {            a[k] = left[i];            i++;        }        else        {            a[k] = right[j];            j++;            count += n1-i; /**此步骤是在归并排序法中加的一句,用来计数求逆序数的数目**/        }    }    return;}void mergesort(int* a, int p, int r){    int q;    if (p < r)    {        q = (p+r)/2;        mergesort(a, p, q);        mergesort(a, q+1, r);        merge(a, p, q, r);    }    return ;}int main(){    int n, i, a[500001];    while (scanf("%d", &n) && n)    {        count = 0;        for (i=0; i<n; i++)        {            scanf("%d", &a[i]);        }        mergesort(a, 0, n-1);        printf("%lld/n", count);    }}


原创粉丝点击