IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 信息学奥赛一本通 1235:输出前k大的数 | OpenJudge 2.4 7617:输出前k大的数 -> 正文阅读

[数据结构与算法]信息学奥赛一本通 1235:输出前k大的数 | OpenJudge 2.4 7617:输出前k大的数

【题目链接】

ybt 1235:输出前k大的数
OpenJudge 2.4 7617:输出前k大的数

【题目考点】

1. 排序

【君义精讲】排序算法

【解题思路】

要输出前k大的数,需要对数字序列做降序排序。由于数据规模达到 1 0 5 10^5 105,所以必须选用复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)的排序方法。
可选的排序方法有归并排序、快速排序、堆排序等。可以选择手写,或使用stl中已有的函数或结构。
由于输入输出数据量较大,建议使用scanf与printf

【题解代码】

解法1:归并排序

  • 手写归并排序
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], t[N], n, k;
void mergeSort(int l, int r)
{
    if(l >= r)
        return;
    int m = (l + r) / 2;
    mergeSort(l, m);
    mergeSort(m+1,r);
    int li = l, ri = m+1, ti = l;
    while(li <= m && ri <= r)
    {
        if(a[li] > a[ri])
            t[ti++] = a[li++];
        else
            t[ti++] = a[ri++];
    }
    while(li <= m)
        t[ti++] = a[li++];
    while(ri <= r)
        t[ti++] = a[ri++];
    for(int i = l; i <= r; ++i)
        a[i] = t[i];
}
int main()
{
    scanf("%d", &n); 
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    scanf("%d", &k);
    mergeSort(1, n);
    for(int i = 1; i <= k; ++i)
        printf("%d\n", a[i]);
    return 0;
}
  • 使用stable_sort函数
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], n, k;
bool cmp(int x, int y)
{
    return x > y;
}
int main()
{
    scanf("%d", &n); 
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    scanf("%d", &k);
    stable_sort(a+1, a+1+n, cmp);
    for(int i = 1; i <= k; ++i)
        printf("%d\n", a[i]);
    return 0;
}

解法2:快速排序

  • 手写快速排序
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], n, k;
void quickSort(int l, int r)
{  
    if(l >= r)
        return;
    int i = l, j = r;
    int mid = a[(l+r)/2];//将当前序列在中间位置的数定义为分隔数
    while(i <= j)//注意这里不能少了等号
    {
        while(a[i] > mid) 
            i++;  //在左半部分寻找小于等于中间数的数
        while(a[j] < mid)
            j--;    //在右半部分寻找大于等于中间数的数
        if(i <= j) //若找到一组与排序目标不一致的数对
        {                               
            swap(a[i], a[j]);//则交换它们 
            i++;
            j--;
        }
    }
    quickSort(l, j);//递归搜索左右区间
    quickSort(i, r);
}
int main()
{
    scanf("%d", &n); 
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    scanf("%d", &k);
    quickSort(1, n);
    for(int i = 1; i <= k; ++i)
        printf("%d\n", a[i]);
    return 0;
}
  • 使用sort函数
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], n, k;
bool cmp(int x, int y)
{
    return x > y;
}
int main()
{
    scanf("%d", &n); 
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    scanf("%d", &k);
    sort(a+1, a+1+n, cmp);
    for(int i = 1; i <= k; ++i)
        printf("%d\n", a[i]);
    return 0;
}

解法3:堆排序

  • 手写堆
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int heap[N], n, k;
//b是否比a高级。堆顶是最高级的元素 
bool isPrior(int a, int b)
{
    return a > b;//a > b:小顶堆, a < b:大顶堆 
} 
//第i结点上移 
void shiftUp(int i)
{
    if(i == 1)//p是根结点 
        return;
    if(isPrior(heap[i/2], heap[i]))
    {
        swap(heap[i], heap[i/2]);
        shiftUp(i/2);
    }
}
//第i结点下沉 
void shiftDown(int i)
{
    if(i > n/2)//如果i是叶子结点
        return; 
    int sel;//选择交换的结点位置 
    if(2*i+1 <= n && isPrior(heap[2*i],heap[2*i+1]))//有右孩子且右孩子值更大 
        sel = 2*i + 1;
    else//没有右孩子或左孩子值更大 
        sel = 2*i; 
    if(isPrior(heap[i],heap[sel]))
    {
        swap(heap[sel], heap[i]);
        shiftDown(sel); 
    }
}
//建堆 
void buildHeap()
{
    for(int i = n/2; i >= 1; --i)
        shiftDown(i); 
}
//插入元素 
void insert(int val)
{
    heap[++n] = val;
    shiftUp(n); 
}
//删除元素 
void del()
{
    swap(heap[1], heap[n]);
    n--;
    shiftDown(1); 
}
//获取堆顶 
int top()
{
    return heap[1];
}
//堆排序 这样做降序排列用小顶堆 
void heapSort()
{
    int tot = n;
    for(int i = 1; i <= tot - 1; ++i)
        del();
}
int main()
{
    scanf("%d", &n); 
    for(int i = 1; i <= n; ++i)
        scanf("%d", &heap[i]);
    scanf("%d", &k);
    buildHeap();
    heapSort();
    for(int i = 1; i <= k; ++i)
        printf("%d\n", heap[i]);
    return 0;
}
  • 使用stl的优先队列
#include <bits/stdc++.h>
using namespace std;
int n, k;
priority_queue<int, vector<int>, less<int> > pq;//less仿函数为:a<b,大顶堆 做降序排序 
int main()
{
    int a;
    scanf("%d", &n); 
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d", &a);
        pq.push(a);
    }
    scanf("%d", &k);
    for(int i = 1; i <= k; ++i)
    {
        printf("%d\n", pq.top());
        pq.pop();
    }
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:31:56  更:2022-04-27 11:34:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:38:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码