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

    输入一个序列求序列中的逆序对

    归并排序代码

    void merge_sort(int *a,int x,int y,int *T)
    {
    if(y-x<=1)return ;
    int m=x+(y-x)/2;
    int p=x,q=m,i=x;
    merge_sort(a,x,m,T);
    merge_sort(a,m,y,T);
    while(p<m||q<y)
    {
    if(q>=y||(p<m&&a[p]<=a[q]))
    T[i++]=a[p++];
    else
    T[i++]=a[q++];
    }
    for(int x;i<y;i++)a[i]=T[i];
    }
    //代码来自紫书

    分治方法,先分开,然后递归求解,最后合并问题。

    将序列分成差不多等长的两部分,统计i和j均在左边或者均在右边的逆序对数,再统计i在左边,j在右边的逆序对数。

    求i,j分别在两边的情况,可以通过上面的排序算法所用的技巧算,因为归并排序最后合并i在左j在右,并且两边有序所以每一次找到a[p]>a[q]就可以判定为是逆序,并且可以判定a[p]到a[m]中间的都大于a[q]。于是 可以直接cnt+=m-p。

    #include<iostream>
    using namespace std;
    int a[100];
    int t[100];
    int cnt=0;
    void merge_sort(int *a,int x,int y,int *T)
    {
        if(y-x>1)
        {
            int m=x+(y-x)/2;
            int p=x,q=m,i=x;
            merge_sort(a,x,m,T);
            merge_sort(a,m,y,T);
            while(p<m||q<y)
            {
                if(q>=y||(p<m&&a[p]<=a[q]))
                    T[i++]=a[p++];
                else
                    {T[i++]=a[q++];cnt+=m-p;}
            }
            for(i=x;i<y;i++)
                a[i]=T[i];
        }
    }
    int main()
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>a[i];
        merge_sort(a,0,n,t);
        cout<<cnt<<endl;
    }
    //代码来自对紫书上修改
  • 相关阅读:
    标识类型模式
    脏检查和快照的故事
    Hibernate入门案例及增删改查
    Oracle函数解析
    Oracle基础及三层分页查询
    java解析xml文档(dom)
    TCP和UDP的聊天
    java线程同步
    试题分析(第三套)
    java线程的简单实现及方法
  • 原文地址:https://www.cnblogs.com/ke-yi-/p/10175820.html
Copyright © 2011-2022 走看看