• 归并排序求逆序对


    我们可以这样考虑:

     

    归并排序是将数列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;
     }
    }

  • 相关阅读:
    031-进阶(日志)
    Django 路由系统
    C++ 面向对象(接口-抽象类)
    C++ 面向对象(多态)
    C++ 面向对象(数据抽象)
    三十、首页列表显示全部问答,完成问答详情页布局
    二十九、制作首页的显示列表
    二十八、发布功能完成
    二十七、登录之后更新导航
    二十六、完成登录功能,用session记住用户名
  • 原文地址:https://www.cnblogs.com/ffhy/p/5661485.html
Copyright © 2020-2023  润新知