zoukankan      html  css  js  c++  java
  • 求逆序对数

    https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

    题目描述

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

    输入描述:

    题目保证输入的数组中没有的相同的数字

    数据范围:

    对于%50的数据,size<=10^4

    对于%75的数据,size<=10^5

    对于%100的数据,size<=2*10^5

    示例1

    输入

    1,2,3,4,5,6,7,0

    输出

    7
    思路: 使用归并排序,merge过程中 因为保证了 左侧数组 与 右侧数组 分别有序,所以在merge过程中统计逆序对数
    对于数组 :
      如果 a[i] > a[j] then j ++; 这样保证了 一旦出现 a[i] <= a[j] 的时候, a[i] > a[m + 1 -> j - 1] 得到由(
    a[i] , a[m+1 : j - 1]
    )构成的逆序对数 j - 1 - m 对;
    #include <iostream>
    #include <vector>
    #include <cstdio>
    #define DEBUG
    
    using namespace std;
    
    #define MOD 1000000007
    class Solution {
    public:
        int cnt = 0;
        void merge(int l, int m, int r, vector<int>& a)
        {
            int i = l, j = m + 1, k = r;
            vector<int>t;
            while(i <= m || j <= r)
            {
                if(i <= m && j <= r)
                {
                    if(a[i] > a[j]){
                        t.push_back(a[j ++]);
                    }else{
                        cnt = ( cnt % MOD + ( j  - m - 1) % MOD) % MOD;
                        t.push_back(a[i ++]);
                    }
                }
                else if(i <= m)
                {
                     cnt = ( cnt % MOD + ( j  - m - 1) % MOD) % MOD;
                     t.push_back(a[i ++]);
                }
                else
                {
                    t.push_back(a[j ++]);
                }
            }
            for(int i = l; i <= r; i ++)
                a[i] = t[i - l];
        }
    
        void divide(int l, int r, vector<int>& a)
        {
            if (l < r){
                int m = l + (r - l) / 2;
                divide(l, m, a);
                divide(m + 1,  r, a);
                merge(l, m,  r, a);/*
                cout << "l:" <<l << "   m + 1: "<< m + 1 << "    r:" << r<<endl;
                cout <<"cnt= " <<cnt <<endl;
                for(int i = l; i <= r; i ++)
                {
                    cout << a[i] << " ";
                }cout <<endl;*/
            }
        }
    
        int InversePairs(vector<int>& data) {
            divide(0, data.size() - 1, data);
            return cnt;
        }
    };
    
    int main()
    {
        #ifdef DEBUG
            freopen("input.txt", "r", stdin);
        #endif // DEBUG
        vector<int>d;
        int n, t;
        cin>>n;
        for(int i = 0; i < n; i ++){
            cin>>t;
            d.push_back(t);
        }
        Solution sol;
        cout << sol.InversePairs(d) << endl;
        for(int i = 0; i < n; i ++)
            cout << d[i] << " " ;
        return 0;
    }
    /*
    7
    4 5 6 7 3 4 5
    */
  • 相关阅读:
    “浪潮杯”第九届山东省ACM大学生程序设计竞赛 F: Four-tuples容斥定理
    B
    C. Tourist Problem 2021.3.29 晚vj拉题 cf 1600 纯数学题
    C. Sum of Cubes
    Day29、Python中的异常处理及元类
    isinstance,issubclass,反射,内置方法(__str__,__del__,__call__)
    绑定方法与非绑定方法;classmethod及staticmethod装饰器
    组合,多态,封装
    类的继承
    面向对象编程思想基本介绍,类与对象的基本使用,属性查找,绑定方法
  • 原文地址:https://www.cnblogs.com/luntai/p/7719006.html
Copyright © 2011-2022 走看看