【堆排 && 思路】数据结构实验之排序四:寻找大富翁

 

一个看似很水但很坑的题:数据结构实验之排序四:寻找大富翁
这题时间压的很短只有200ms,用平常的堆排序。直接T,别问我怎么知道(心累啊),要不也不会写这篇博客。直接上代码。这题关键在于用了一个很巧妙的思想,没有去对所有1e6的数据全部堆排,而转去维护了m个小顶堆,这样效率大大提高。最终能维护成一个m个最大元素组成的小顶堆。最终输出就好了。(*注:记得维护的是小顶堆而输出要从大到小。所以还要进行一个简单的排序。)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 100005
long long int a[N];
int size;

void Insert(long long int m)
{
    a[++size] = m;
    int i;
    for(i = size; i != 0; i /= 2)
    {
        if(a[i] < a[i/2])
        {
            long long int t = a[i];
            a[i] = a[i/2];
            a[i/2] = t;
        }
        else
            break;
    }
}

void Adjustment()
{
    int i, x;
    for(i = 1; 2 * i <= size; i = x)
    {
        if(2 * i + 1 <= size && a[i * 2] > a[i * 2 + 1])
            x = i * 2 + 1;
        else
            x = i * 2;
        if(a[i] > a[x])
        {
            long long int t = a[i];
            a[i] = a[x];
            a[x] = t;
        }
        else
            break;
    }
}

int main()
{
    int n, i, m;
    scanf("%d%d", &n, &m);
    for(i = 0; i < m; i++)//创建小顶堆
    {
        int x;
        scanf("%d", &x);
        Insert(x);
    }
    for(i = m;i < n; i++)//维护小顶堆
    {
        int x;
        scanf("%d", &x);
        if(x > a[1])
        {
            a[1] = x;
            Adjustment();
        }
    }
    for(i = m;i > 0; i--)//再做一个排序
    {
        int t = a[1];
        a[1] = a[i];
        a[i] = t;
        size--;
        Adjustment();
    }
    for(i = 1;i <= m; i++)
    {
        if(i == m)
            printf("%lld\n", a[i]);
        else
            printf("%lld ", a[i]);
    }
    return 0;
}
posted @ 2018-12-28 18:58  Mr.XuAMis.Liu  阅读(252)  评论(0编辑  收藏  举报