zoukankan      html  css  js  c++  java
  • Algorithm Description

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/A

    题意:

          输入n,再输入n个数a[i],以输入的顺序排列,找出相邻元素最少要交换多少次才能让所有数以从小到大的顺序排列。n为0时结束循环。

          案例:

          intput

          5

          9

          1

          0

          5

          4

          0

          output

          6

    思路分析:

              n<500000,用两层循环,时间复杂度为O(n2),显然这会超时,归并排序,它的时间复杂度为O(nlogn)。所以用归并排序求解。

              利用递归,把序列划分成元素个数尽可能相等的两半,直到y-x<=1,一层一层的进行判断,当右边的数小于左边的数,把右边的数的位置减去左边的数的位置,即为交换次数,再把两个数重新储存。

            注意:a[i]的范围过大,要记得用long long。

    源代码如下:

     1 #include<iostream>
     2 #define maxn 500005
     3 using namespace std;
     4 long long s,a[maxn],T[maxn];
     5 void merge_sort(int x,int y,long long *b,long long *t)           //归并排序
     6 {
     7     if(y-x>1)
     8     {
     9         int m=x+(y-x)/2;
    10         int p=x,q=m,i=x;
    11         merge_sort(x,m,b,t);            //左序列
    12         merge_sort(m,y,b,t);            //右序列
    13         while(p<m||q<y)
    14         {
    15             if(q>=y||(p<m&&b[p]<=b[q])) t[i++]=b[p++];         
    16             else
    17             {
    18                 t[i++]=b[q++];
    19                 s+=m-p;                //记录交换次数
    20             }                     
    21         }
    22         for(i=x;i<y;i++) b[i]=t[i];      //重新储存
    23     }
    24 }
    25 int main()
    26 {
    27     int n;cin>>n;
    28     while(n)
    29     { 
    30         s=0;
    31         for(int i=0;i<n;i++)
    32             cin>>a[i];
    33         merge_sort(0,n,a,T);
    34         cout<<s<<endl;
    35         cin>>n;
    36     }
    37     return 0;
    38 }

             

           

  • 相关阅读:
    第一次项目总结
    8.16 CSS知识点7
    2016y9m22d 博文分享
    2016y9m8d
    2016y9m7d
    2016y9m6d
    2016y9m5d
    2016.9.2博文分享!
    2016y8m16d
    2016y8m15d
  • 原文地址:https://www.cnblogs.com/q-c-y/p/4702473.html
Copyright © 2011-2022 走看看