1. 程式人生 > >ACM_小明滾出去?(歸並排序求逆序數)

ACM_小明滾出去?(歸並排序求逆序數)

思路 name ont ans void long 輸出 lld sort

小明滾出去?

Time Limit: 2000/1000ms (Java/Others)

Problem Description:

老師:“小明,寫一個排序算法”;
小明:
void mysort(int a[],int n) //n為數組a的元素個數
{
    int i,j;
    for(j=0;j< n-1;j++)
        for(i=0;i< n-1;i++)
        {
            if(a[i] >a[i+1])//數組元素大小按升序排列
            {
            	swap(a[i],a[i+1]);//交換
            }
        }
}
老師:“好,那麽,問題來了,給定一個數組,按你這個算法排序,需要的交換次數是多少?回答對了今天就可以不用滾出去。”
小明按他的這個算法試了一下,發現超時了,不想天天被老師叫滾出去,小明只好求助於你,你能幫助小明今天不用滾出去麽?

Input:

輸入包含多組數據(EOF),每組數據第一行是一個整數n(1<=n<=10^5),第二行有n個整數(<=10^5);

Output:

對於每組數據,輸出小明排序算法的交換次數。

Sample Input:

3
1 3 2
5
5 4 3 2 1
4
1 2 3 4

Sample Output:

1
10
0
解題思路:求冒泡排序的交換次數其實就是求這個序列的逆序數,歸並排序水過!
AC代碼:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+5;
 4 typedef long
long LL; 5 int n,a[maxn],tmp[maxn];LL ans; 6 void _merge(int l,int m,int r){ 7 int i=l,j=m+1,k=l; 8 while(i<=m&&j<=r){ 9 if(a[i]>a[j]){tmp[k++]=a[j++];ans+=(LL)m-i+1;} 10 else tmp[k++]=a[i++]; 11 } 12 while(i<=m)tmp[k++]=a[i++]; 13 while(j<=r)tmp[k++]=a[j++];
14 for(int i=l;i<=r;++i)a[i]=tmp[i]; 15 } 16 void _merge_sort(int l,int r){ 17 if(l<r){ 18 int m=(l+r)>>1; 19 _merge_sort(l,m); 20 _merge_sort(m+1,r); 21 _merge(l,m,r); 22 } 23 } 24 int main(){ 25 while(~scanf("%d",&n)){ 26 for(int i=0;i<n;++i)scanf("%d",&a[i]); 27 ans=0;_merge_sort(0,n-1); 28 printf("%lld\n",ans); 29 } 30 return 0; 31 }

ACM_小明滾出去?(歸並排序求逆序數)