poj 2299_归并排序

来源:互联网 发布:java通过ip获取地区 编辑:程序博客网 时间:2024/05/23 14:31

题目描述:

  给一个序列,求若只交换相邻的两个数,令序列达到升序/降序的交换次数。

解题思路:

  介个,就等于是求最后正序的序列,和最初序列中,向前移动的元素的移动位数。可知,必须找一个稳定的排序算法。——归并排序,在归并过程中计算元素前推的位置数。(比较两个相邻元素的排序方法可以做到稳定。)

 

代码:(注意500000个数,最终的结果大于int能表示范围)

#include <stdio.h>
#include <stdlib.h>
#define N  500001

int array[N], array_new[N];
long long sum = 0;

void Merge(int m, int index, int n)
{
   int k=m,j,i;
  
   for(i=m,j=index+1;i<=index&&j<=n;++k )
   {
     if(array[i] <= array[j])
        array_new[k] = array[i++];
     else
     {
        sum += j-k;
        array_new[k] = array[j++];
     }
   }
  while(i<=index)
    array_new[k++] = array[i++];
  while(j<=n)
    array_new[k++] = array[j++];
  
   for(i=m; i<=n;i++)
     array[i] = array_new[i];
}

void MSort(int m, int n)
{
   int index;
   if(m == n)
     array_new[m] =array[n];
   else
   {
     index = (m+n)/2;
     MSort(m,index);
     MSort(index+1,n);
     Merge(m, index, n);
   }
}
main()
{
   intn,i;   
  scanf("%d",&n);
   while(n!=0)
   {
      sum = 0;
      for(i=1;i<=n;i++)
         scanf("%d",&array[i]);
      MSort(1,n);
      printf("%lld\n",sum);
 
      scanf("%d",&n);
   }
   //system("pause");
   return 0;
}

 

原创粉丝点击