• 九度OJ 1348:数组中的逆序对 (排序、归并排序)


    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:2777

    解决:656

    题目描述:
    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
    输入:
    每个测试案例包括两行:
    第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
    第二行包含n个整数,每个数组均为int类型。
    输出:
    对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。
    样例输入:
    4
    7 5 6 4
    样例输出:
    5

    思路:

    看了别人的思路才明白的。

    这个题要对数组进行归并排序,排序过程中的操作次数就是逆序对的个数。

    注意:全局变量count不能声明为int型,必须为long long型。因为题目中说数组最大为10^5,那么最大逆序对为(10^5-1)*10^5/2,这个数大约在50亿左右,超过了int型的表示范围。


    代码:

    #include <stdio.h>
     
    #define N 100000
     
    void print(int *a, int n)
    {
        for (int i=0; i<n; i++)
            printf("%d ", a[i]);
        printf("
    ");
    }
     
    long long mergeSort(int a[N], int s, int e)
    {
        if (s == e)
            return 0;
     
        long long count;
        int m = (s+e)/2;
        count = 0;
        count += mergeSort(a, s, m);
        count += mergeSort(a, m+1, e);
     
        int b[N];
        int i, j, k;
        i = s;
        j = m+1;
        k = s;
        while (i<=m || j<=e)
        {
            if (j > e || ( i <= m && a[i] > a[j]))
            {
                b[k++] = a[i];
                count += (e-j+1);
                //printf("i,j,m,e=%d,%d,%d,%d count=%lld
    ", i,j,m,e,count);
                i++;
            }
            else
            {
                b[k++] = a[j];
                j++;
            }
        }
        //print(a+s, e-s+1);
        //printf("s=%d, e=%d, count=%lld
    ", s, e, count);
        for (i=s; i<=e; i++)
            a[i] = b[i];
     
        return count;
    }
     
    int main(void)
    {
        int n, i;
        int a[N];
        long long count;
     
        while (scanf("%d", &n) != EOF)
        {
            for(i=0; i<n; i++)
                scanf("%d", &a[i]);
     
            /*
            count = 0;
            for(i=0; i<n; i++)
            {
                for(j=i+1; j<n; j++)
                {
                    if (a[i] > a[j])
                        count ++;
                }
            }
            */
     
            count = mergeSort(a, 0, n-1);
     
            printf("%lld
    ", count);
        }
     
        return 0;
    }
    /**************************************************************
        Problem: 1348
        User: liangrx06
        Language: C
        Result: Accepted
        Time:100 ms
        Memory:7864 kb
    ****************************************************************/


  • 相关阅读:
    WCF双工通讯以及客户端间的间接通讯
    认识IoC
    学习“迷你ASP.NET MVC框架”后的小结
    MVP的PV模式与SC模式
    Android学习笔记(九) 视图的应用布局效果
    C# 动态编译
    C#中协变与抗变(逆变)
    线程池ThreadPool的初探
    关于异步的初步认识
    仿Office的程序载入窗体
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083785.html
Copyright © 2020-2023  润新知