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

  • 相关阅读:
    C connect实现Timeout效果(Linux)
    QSS网址
    C实现读写文件
    crond守护进程实现定时监控某进程占有内存的大小
    Ubuntu17安装Chrome有效
    Ubuntu16安装wine(转)
    直方图均衡化
    函数后面的const修饰符的作用
    C 线程学习记录
    Override Fuction 调用——到底使用的是谁的函数
  • 原文地址:https://www.cnblogs.com/ffhy/p/5661485.html
Copyright © 2011-2022 走看看