zoukankan      html  css  js  c++  java
  • 1908 逆序对

    1908 逆序对

    难度:普及+/提高

    题目类型:递归/分治

    提交次数:1

    涉及知识:归并排序

    题目描述

    猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。

    代码:

    #include<iostream>
    using namespace std;
    const int N = 100010;
    int a[N];
    int temp[N];
    int ans;
    void merge(int l, int m, int r){
        int i = l, k = l, j = m+1;
        while(i<=m&&j<=r){
            if(a[i]>a[j]){
                temp[k++] = a[j++];
                ans+=m-i+1;
            }
            else
                temp[k++] = a[i++];
        }
        while(i<=m) temp[k++] = a[i++];
        while(j<=r) temp[k++] = a[j++];
        for(i = l; i<=r; i++)
            a[i] = temp[i];
    }
    void merge_sort(int l, int r){
        if(l < r){
            int mid = (l + r)/2;
            merge_sort(l, mid);
            merge_sort(mid+1, r);
            merge(l, mid, r);
        }
    }
    int main(){
        int n, i;
        cin>>n;
        for(i = 1; i <= n; i++)
            cin>>a[i];
        merge_sort(1, n);
        cout<<ans<<endl;
        return 0;
    } 

    备注:

    很经典的一道题,结课考试也考过,思路就是利用归并排序的特点,在merge中加入“关键的一行”。主要目的是巩固归并排序,看了半天终于背下来了,程序是自己写的,而且居然一遍就写对了∩_∩,看来记忆力还行(其实是因为把每一行代码都理解吃透了才记住。。),如果不多写写肯定又忘了。那关键的一行,第一次看的时候还看不明白,感觉那时候自己好傻(好吧现在也不怎么聪明),很简单嘛,分别排序的过程不能改变跨组的逆序对,merge的时候如果a[i]>a[j](按理说a[j]应该是比最后一个a[i]大的),a[j]这样一抢了先,有多少个a[i]会很难过呢?自然就是m-i+1个了!嗯,这么解释清楚不清楚?反正我觉得比较清楚。以后不懂的细节还是要花时间细细想想。

  • 相关阅读:
    1175_UPDATE报错[转]
    python&sql
    MySQL安装
    python[1]
    一道题理解层次分析法【转】
    神经网络编程入门
    监督学习和无监督学习
    ML-3Normal equation
    ML_note1
    CTF之隐写总结
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/5784793.html
Copyright © 2011-2022 走看看