开发者社区> 问答> 正文

请教北大oj上的2299题

他是说类似于冒泡排序,求解交换了多少次。但是如果使用冒泡,会导致超时

展开
收起
知与谁同 2018-07-21 12:19:12 1531 0
1 条回答
写回答
取消 提交回答
  • 这实际上是一个求逆序数的问题。要用到归并排序的思想。建议你好好看看算法导论第二章的内容以及课后习题。
    另外,若要ac,一定要将存储逆序数的变量声明为long long。我当时就在这个地方卡了n久,上网求助才解决的。希望你注意。
    附上代码:
    #include <stdio.h>
    long a[500005];

    long long merge_inversions(long p, long q, long r)
    {
    long n1 = q - p + 1;
    long n2 = r - q;
    long *left = new long[n1+1];
    long *right = new long[n2+1];
    long i, j;
    for(i = 0; i < n1; i++)
    left[i] = a[p + i];
    for(j = 0; j < n2; j++)
    right[j] = a[q + j + 1];
    left[n1] = 1000000000;
    right[n2] = 1000000000;
    i = 0;
    j = 0;
    long long inversions = 0;
    bool counted = false;
    for(long k = p; k <= r; k++)
    {
    if( counted == false && left[i] > right[j])
    {
    inversions += (n1 - i);
    counted = true;
    }
    if( left[i] <= right[j] )
    {
    a[k] = left[i];
    i++;
    }
    else
    {
    a[k] = right[j];
    j++;
    counted = false;
    }
    }
    delete []left;
    delete []right;
    return inversions;
    }

    long long count_inversions(long p, long r)
    {
    long long inversions = 0;
    if( p < r )
    {
    long q = (p + r)/2;
    inversions += count_inversions(p, q);
    inversions += count_inversions(q+1, r);
    inversions += merge_inversions(p, q, r);
    }
    return inversions;
    }

    int main()
    {
    long n;
    while( scanf("%ld", &n) && n != 0 )
    {
    for(long i = 0; i < n; i++)
    {
    scanf("%ld", &a[i]);
    }
    long long count = count_inversions(0, n-1);
    printf("%lld\n", count);
    }
    return 0;
    }
    2019-07-17 22:52:11
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
诚 .xin赢天下 立即下载
诚Xin赢天下 立即下载
学长学姐成长记 立即下载