• 求逆序数(归并排序)


    求逆序数

    时间限制:2000 ms  |  内存限制:65535 KB
    难度:5
    描述

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。

    现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。

    比如 1 3 2 的逆序数就是1。

    输入
    第一行输入一个整数T表示测试数据的组数(1<=T<=5)
    每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000)
    随后的一行共有N个整数Ai(0<=Ai<1000000000),表示数列中的所有元素。

    数据保证在多组测试数据中,多于10万个数的测试数据最多只有一组。
    输出
    输出该数列的逆序数
    样例输入
    2
    2
    1 1
    3
    1 3 2
    样例输出
    0
    1
    题解:归并排序:要用lOng long 真心错了半天;
    8 6 4 2 7 5 3 1

    6 8 2 4 5 7 1 3
    4
    2 4 6 8 1 3 5 7
    1 2 4 6 8 3 5 7
    1 2 3 4 6 8 5 7
    12
    1 2 3 4 5 6 7 8
    22
    4+3+2+1


    4 4 2 3 5 5 1 6

    2 3 4 4 1 5  5 6
    6
    1 2 3 4 4 5 5 6
    10
    借助理解;
    /*
    *  归并排序是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为
    *  若干个子序列,每个子序列是有序的,然后再把有序的子序列合并为整体有序序列
    *  归并排序是分治算法的一个典型的应用,而且是稳定的一种排序,这题利用归并排序
    *  的过程中,计算每个小区间的逆序数,进而得到大区间的逆序数。那么,问题就解决了。
    *
    */
    代码:
    #include<stdio.h>
    #include<string.h>
    const int MAXN=1000010;
    int num[MAXN],temp[MAXN];
    long long ans;
    void mergesort(int s,int m,int e){
        int i=s,j=m+1,k=s;
        while(i<=m&&j<=e){
            if(num[i]<=num[j])temp[k++]=num[i++];
            else{
                ans+=j-k;
                temp[k++]=num[j++];
            }
        }
        while(i<=m)temp[k++]=num[i++];
        while(j<=e)temp[k++]=num[j++];
        for(int i=s;i<=e;i++)num[i]=temp[i];
        //while(s<=e)num[s++]=temp[s];//赋值运算符是先对等号的右边进行计算
    }
    void ms(int l,int r){
        if(l<r){
            int mid=(l+r)/2;
            ms(l,mid);
            ms(mid+1,r);
            mergesort(l,mid,r);
        }
    }
    int main(){
        int T,N;
        scanf("%d",&T);
        while(T--){
            ans=0;
            scanf("%d",&N);
            for(int i=1;i<=N;i++)scanf("%d",num+i);
            ms(1,N);
        //    for(int i=1;i<=N;i++)printf("%d ",num[i]);puts("");
            printf("%lld
    ",ans);
        }
        return 0;
    }
    java:
    import java.util.Scanner;
    
    
    public class MergeSort {
        public static int[] a, b;
        public static long ans = 0;
        public static void main(String[] args) {
            int l, T;
            Scanner cin = new Scanner(System.in);
            T = cin.nextInt();
            while(T-- > 0){
                l = cin.nextInt();
                a = new int[l + 1];
                b = new int[l + 1];
                
                for(int i = 1; i <= l; i++){
                    a[i] = cin.nextInt();
                }
                ans = 0;
                ms(1, l);
    //            for(int i = 1; i <= l; i++){
    //                System.out.printf("%d ", a[i]);
    //            }
    //            System.out.println();
                System.out.println(ans);
            }
        }
        public static void mergeSort(int l, int m, int r){
            int i = l, j = m + 1, k;
            k = l;
            while(i <= m && j <= r){
                if(a[i] <= a[j]){
                    b[k++] = a[i++];
                }
                else{
                    ans += j - k;
                    b[k++] = a[j++];
                }
            }
            while(i <= m)
                b[k++] = a[i++];
            while(j <= r)
                b[k++] = a[j++];
            
            for(k = l; k <= r; k++){
                a[k] = b[k];
            }
        }
        public static void ms(int l, int r){
            if(l < r){
                int m = (l + r) / 2;
                ms(l, m);
                ms(m+1, r);
                mergeSort(l, m, r);
            }
        }
    }


  • 相关阅读:
    Spring Boot 详细简介
    Linux 安装 MySQL 8 数据库(图文详细教程)
    有了这个日期工具类,让日期转化不再烦恼
    Linux常用实用命令
    Java分割中英文,并且中文不能分割一半?
    Spring MVC或Spring Boot配置默认访问页面不生效?
    js如何判断当前页面是否处于激活状态
    博客园 & 陌上花开HIMMR | 脱单倒计时!只能帮你到这了
    博客园 & 陌上花开HIMMR | 距2020年脱单,只剩34天!
    博客园 & 陌上花开HIMMR | 脱单倒计时!刚过完10.24的你,还想一个人过11.11吗?
  • 原文地址:https://www.cnblogs.com/handsomecui/p/4803627.html
Copyright © 2020-2023  润新知