zoukankan      html  css  js  c++  java
  • 归并排序求逆序对

    我们可以这样考虑:

     

    归并排序是将数列a[l,h]分成两半a[l,mid]和a[mid+1,h]分别进行归并排序,然后再将这两半合并起来。

    在合并的过程中(设l<=i<=mid,mid+1<=j<=h),当a[i]<=a[j]时,并不产生逆序数;当a[i]>a[j]时,在

    前半部分比a[i]大的数都比a[j]大,将a[j]放在a[i]前面的话,逆序数要加上mid+1-i。因此,可以在归并

    序中的合并过程中计算逆序数.

     

    题目:http://poj.org/problem?id=1804


    C++代码

    #include<iostream>
    #include<cstring>
    using namespace std;
    int a[1001],rr[1001],n,tot;
    void merge_sort(int l,int r)
    {

     int mid,i,j,k;
     if(l==r) return;
     mid=(l+r)/2;
     merge_sort(l,mid);
     merge_sort(mid+1,r);
     i=l;j=mid+1;k=l;
     while(i<=mid&&j<=r)
     {
         if(a[i]<=a[j]){
         rr[k++]=a[i++];
         }
         else{                 //a[i]>a[j]时 则前半部分比a[i]大的数都比a[j]大
             tot+=mid-i+1;    // 由于此时前半部分a[i]是有序的 则一共有mid-i+1个逆序对
          rr[k++]=a[j++];
         }
     }
         while(i<=mid) rr[k++]=a[i++];
         while(j<=r)   rr[k++]=a[j++];
     for (int i=l;i<=r;i++)
     a[i]=rr[i];
    }
    int main()
    {
     int num=1;
     cin>>n;
     for (int i=1;i<=n;i++)
     {
      int n1;
      cin>>n1;
      memset(a,0,sizeof(a));
      memset(rr,0,sizeof(rr));
      tot=0;                 //初始化
      for(int i=1;i<=n1;i++)
      cin>>a[i];
      merge_sort(1,n1);
      cout<<"Scenario #"<<num<<endl;
      num++;
      cout<<tot<<endl;
     }
    }

  • 相关阅读:
    错题本
    前端常用的代码片段
    前端生成二维码 jquery.qrcode.js
    jquery获取第几个元素的方法总结
    Jquery 获取第一个子元素
    个人作品(2016.3.17更新)
    360度全景制作
    期末项目_通用教学管理系统(季远琦&庞思瑶)
    java ee 第四周作业
    Web Service和EJB的区别
  • 原文地址:https://www.cnblogs.com/ffhy/p/5661485.html
Copyright © 2011-2022 走看看