zoukankan      html  css  js  c++  java
  • POJ 2299 -- Ultra-QuickSort

    Ultra-QuickSort
    Time Limit: 7000MS   Memory Limit: 65536K
    Total Submissions: 65986   Accepted: 24686

    Description

    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
    9 1 0 5 4 ,

    Ultra-QuickSort produces the output 
    0 1 4 5 9 .

    Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

    Input

    The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

    Output

    For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

    Sample Input

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0
    

    Sample Output

    6
    0
    

    Source

     
    题意:
    输入n个数,问至少经过多少次两两交换,可以得到一个升序序列
    n < 500,000 -- the length of the input sequence
     0 ≤ a[i] ≤ 999,999,999
     
    解题:
    1)利用归并排序求逆序数
    一个乱序序列的 逆序数 = 在只允许相邻两个元素交换的条件下,得到有序序列的交换次数

    注意保存逆序数的变量t,必须要用__int64定义,int一定会溢出的,而long long 在现在的VC编译器已经无法编译了。

    注意__int64类型的输出必须使用指定的c格式输出,printf(“%I64d”,t);

    cout是无法输出__int64类型的

    序列数组s[]用int就足够了,每个元素都是小于10E而已

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 int const maxa = 500005;
     5 __int64 ans;//逆序数
     6 int a[maxa];//存储n个数
     7 
     8 void Merge(int left,int mid,int right)
     9 {
    10     int len_l = mid-left+1;
    11     int len_r = right-mid;
    12     int* aLeft = new int[len_l+2];
    13     int* aRight = new int[len_r+2];
    14     for(int i=1;i<=len_l;i++)
    15         aLeft[i] = a[left+i-1];
    16     aLeft[len_l+1] = 10000000000;//设置一个很大的上界防止溢出
    17     for(int i=1;i<=len_r;i++)
    18         aRight[i] = a[i+mid];
    19     aRight[len_r+1] = 10000000000;//设置一个很大的上界防止溢出
    20     int m=1,n=1;
    21     for(int i=left;i<=right;i++)
    22     {
    23         if(aLeft[m] <= aRight[n])
    24             {
    25                 a[i] = aLeft[m];m++;
    26             }
    27         else{
    28             ans+=len_l-m+1;
    29             a[i] = aRight[n];n++;
    30         }
    31     }
    32     delete aLeft;
    33     delete aRight;
    34     return;
    35 
    36 }
    37 
    38 void mergeSort(int left,int right)
    39 {
    40     if(left<right)
    41     {
    42         int mid = (left + right)/2;
    43         mergeSort(left,mid);
    44         mergeSort(mid+1,right);
    45         Merge(left,mid,right);
    46     }
    47     return;
    48 }
    49 
    50 int main()
    51 {
    52     int n;
    53     while(cin>>n && n!=0)
    54     {
    55         for(int i=1;i<=n;i++)
    56             cin>>a[i];
    57         ans = 0;
    58         mergeSort(1,n);
    59         printf("%I64d
    ",ans);
    60     }
    61 
    62     return 0;
    63 }

    为什么要使用归并呢?这是因为输入的数据量可能会达到50W

    下图的测试是使用插入排序,不出意外的超时了

    所以使用归并排序,时间复杂度为O(nlogn)

    只有堆排序归并排序时间复杂度可以控制在O(nlogn),因为他们都用用空间换时间,其他的排序算法在最坏的情况下,时间复杂度均为O(n^2)

    2)树状数组

    树状数组例题(poj2299)

    树状数组详细讲解,不会算法也能看懂哦~

    记录一下,以后再学习……

  • 相关阅读:
    java SSM 框架 多数据源 代码生成器 websocket即时通讯 shiro redis 后台框架源码
    PHP5.5.13 + Apache2.4.7安装配置流程详解
    mybatis-generator 自动生成mapper以及实体类
    spring cloud之Feign的使用
    spring cloud 初体验
    redis 分布式锁
    Activiti 工作流之所学所感(基本配置) DAY1
    druid 连接池加密算法
    ssm+redis整合(通过aop自定义注解方式)
    aop (权限控制之功能权限)
  • 原文地址:https://www.cnblogs.com/yxh-amysear/p/8436834.html
Copyright © 2011-2022 走看看