hrbust/哈理工oj 1526 小猴和冒泡【归并排序】

小猴和冒泡

Time Limit: 1000 MS

Memory Limit: 32768 K

 

Total Submit: 188(58 users)

Total Accepted: 61(39 users)

Rating: 

Special Judge: No

 

Description

 

小猴同学遇见了一道难题:给出一个长度为n的序列,将其变成递增序列。

 

可能对于你来说并不算难题,因为一个qsort就完全可以解决,但是对于小猴同学来说就是个难题了,因为他只会冒泡。

 

冒泡的思想相信大家都会,每次比较相邻两个数的大小,如果想要得到递增序列,那么前一个数大于后一个数就要把它们交换一下位置,经过n-1趟扫描就能得到想要的递增序列。

 

但是冒泡的时间复杂度是O(n^2),经常会超时,我们假设每作一次交换需要1ms,而小猴同学遇到的难题时间限制是1000000ms,现在请你帮助小猴同学判断一下他的冒泡算法是否会超时。

Input

本题测试数据不超过200组。对于每组测试数据,第一行输入一个整数n(1<=n<=5000),表示这个序列有n个数,接下来一行有n个数,每两个数之间用空格隔开,代表给出的序列。

Output

对于每组测试数据,如果小猴程序运行的时间小于难题的时间限制,则输出"xiaohouV5!",否则输出"xiaohouTLE!"。(如果小猴程序运行的时间和限制的时间相等,则判TLE)。

 

Sample Input

4

2 1 4 3

Sample Output

xiaohouV5!

Author

小猴


做了这个题,学习了一下归并排序,也算是浅显的了解了一下归并排序和其中的特点。

思路:首先我们要知道归并排序的特点,才能做这个题,首先呢,归并排序采用了递归分治的思想,先对小的区间归并排序,再对大的区间归并排序,这样的一个算法保证了数据的相对位子,其实也就是能通过归并排序找到交换次数,这个问题我们稍后再谈,我们先对一个小小的例子进行分析(首先,如果您还不知道归并排序是什么,归并排序是怎样操作的,这里有篇博客写的还是比较好的,先学习了,再回来做题更好理解:http://www.cnblogs.com/jillzhang/archive/2007/09/16/894936.html):


假设输入的是4个数:3 2 1 4

首先递归到最深然后处理3,2这两个数,将其排序为2 3,然后递归到1 4这两个数,不需要排序,最后将其归并,处理 2 3 1 4这四个数,最终排序得到 1 2 3 4

在归并排序的操作中,是将几个数分成两个集合,对于其中两个集合的数比较大小,然后取小的放在tmp【】数组里边,其实在这个操作过程中,也就是相当于冒泡里边的交换操作,只不过在这里一次操作顶冒泡排序里边很多次操作(所以归并排序不会超时还能计算出冒泡次数),我们还是拿刚刚的例子来说,假如处理3 2这两个数的时候,首先取2放在tmp【】数组里边,然后再取3,其实就相当于冒泡里边交换一次的操作。那么在处理2 3 1 4这四个数的时候,我们首先取1放在tmp【】数组里边,然后是2、3、4,其实就相当于1和3换一次,再和2换一次,使得序列最终变成1 2 3 4.因为归并排序保证了相对位子这种特性,所以我们可以通过归并排序这样的伪交换操作,计算出冒泡排序一共需要多少次操作。

具体内容对应代码理解:

#include<stdio.h>
#include<string.h>
using namespace std;
int a[5005];
int b[5005];
int cont;
void mergesort(int l,int r)
{
    int i,j,k,m;
    if(l<r)
    {
        m=(r+l)>>1;
        mergesort(l,m);
        mergesort(m+1,r);
        k=l;
        for(i=l,j=m+1; i<=m&&j<=r;)
        {
            if(a[i]>a[j])
            {
                b[k++]=a[j++],cont+=m-(i-1);//相当于线性交换了这么多次
            }
            else b[k++]=a[i++];
        }
        while(i<=m)b[k++]=a[i++];
        while(j<=r)b[k++]=a[j++];
        for(i=l; i<=r; i++)a[i]=b[i];
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        cont=0;
        mergesort(1,n);
        //printf("%d\n",cont);
        if (cont< 1000000)
        {
            printf("xiaohouV5!\n");
        }
        else
        {
            printf("xiaohouTLE!\n");
        }
    }
}




你可能感兴趣的:(1526,1526,hrbust,哈理工oj)