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;
     }
    }

  • 相关阅读:
    非线性滤波:中值滤波;双边滤波
    线性滤波:方框滤波、均值滤波、高斯滤波
    输入输出XML和YAML文件
    图像对比度、亮度值调整
    opencv图像混合,分离颜色通道、多通道图像混合
    访问图像的三种方法
    Opencv
    INSERT增加数据记录
    MySQL 语言大全
    text
  • 原文地址:https://www.cnblogs.com/ffhy/p/5661485.html
Copyright © 2011-2022 走看看