C小加

厚德 博学 求真 至善 The bright moon and breeze
posts - 145, comments - 195, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Ural 1090. In the Army Now 解题报告

Posted on 2012-01-16 15:12 C小加 阅读(1302) 评论(0)  编辑 收藏 引用 所属分类: 解题报告
利用归并排序求逆序对数,只需要在裸体的归并排序的适当地方加上cnt=n1-i就OK了。很好理解的。

#include<cstdio>
#include<iostream>
using namespace std;
const int MAXM=10003;
const int INF=0x7fffffff-1;
int cnt;
// 归并排序中的合并算法
 void Merge(int array[], int start, int mid, int end)
  {
     int temp1[MAXM/2+1], temp2[MAXM/2+1];
     int n1, n2;
     n1 = mid - start + 1;
     n2 = end - mid;

     // 拷贝前半部分数组
     for (int i = 0; i < n1; i++)
      {
         temp1[i] = array[start + i];
     }
     // 拷贝后半部分数组
     for (int i = 0; i < n2; i++)
      {
         temp2[i] = array[mid + i + 1];
     }
     // 把后面的元素设置的很大
     temp1[n1] = temp2[n2] = INF;
     // 逐个扫描两部分数组然后放到相应的位置去
     for (int k = start, i = 0, j = 0; k <= end; k++)
      {
         if (temp1[i] <= temp2[j])
          {
             array[k] = temp1[i];
             i++;
         }
         else
          {
              cnt+=n1-i;//逆序对的个数
             array[k] = temp2[j];
             j++;
         }
     }
 }

 // 归并排序
 void MergeSort(int array[], int start, int end)
  {
     if (start < end)
      {
         int i;
         i = (end + start) / 2;
         // 对前半部分进行排序
         MergeSort(array, start, i);
         // 对后半部分进行排序
         MergeSort(array, i + 1, end);
         // 合并前后两部分
         Merge(array, start, i, end);
     }
 }

 int main()
 {
     int n,k;
     int arr[MAXM];
     int largemerge=0;
     int num;
     scanf("%d %d",&n,&k);
     for(int j=1;j<=k;j++)
     {
         cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",arr+i);
        }
        MergeSort(arr,0,n-1);
        if(cnt>largemerge)
        {
            largemerge=cnt;
            num=j;
        }
     }
     printf("%d\n",num);
 }

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理