寻找大富翁

寻找大富翁


一、目的

-掌握堆排序
-掌握sort的用法


二、实验内容与设计思想

寻找大富翁

胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人。假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁。

输入格式:
输入首先给出两个正整数N(≤10^6)和M(≤10),其中N为总人数,M为需要找出的大富翁数;接下来一行给出N个人的个人资产值,以百万元为单位,为不超过长整型范围的整数。数字间以空格分隔。

输出格式:
在一行内按非递增顺序输出资产排前M位的大富翁的个人资产值。数字间以空格分隔,但结尾不得有多余空格。

输入样例:
8 3
8 12 7 3 20 9 5 18
输出样例:
20 18 12


题目分析:

代码重点在于判断排序条件的函数


1.排序直接使用sort
函数相关伪代码

1.bool compare(int a,int b)
    return a>b;
2.
for(i=0;i<x;i++)
|cin>>a[i];
sort(a.begin(),a.end(),compare);
if(x<m)
|m=x;
for(i=0;i<m;i++)
|cout<<a[i];
|if(i<m-1)
||cout<<" ";

函数代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool compare(int a,int b){
    return a>b;
}
int main()
{
    int x,m,i;
    cin>>x>>m;
    vector<int>a(x);
    for(i=0;i<x;i++){
        cin>>a[i];
    }
    sort(a.begin(),a.end(),compare);
    if(x<m){
        m=x;
    }
    for(i=0;i<m;i++){
        cout<<a[i];
        if(i<m-1){
        cout<<" ";
        }
    }
    return 0;
}

2.使用堆排序
函数相关伪代码

1.交换函数
void swap(int &a,int &d)
    int k;
    k=a;
    a=d;
    d=k;
2.调整为最大堆
void tui(vector<int>&a,int n,int m)
k=m;
l=2*m+1;
r=2*m+2;
if(l<n&&a[l]>a[k])
|k=l;
if(r<n&&a[r]>a[k])
|k=r;
if(k!=m)
|swap(a[m],a[k]);
|tui(a,n,k);
3.排序
void tui1(vector<int>&a,int n,int m)
for(i=n/2-1;i>=0;i--)
|tui(a,n,i);
for(i=n-1;i>=n-m;i--)
|swap(a[0],a[i]);
|tui(a,i,0);
4.主函数
for(i=0;i<n;i++){
|cin>>a[i];
if(n<m)
|m=n;
tui1(a,n,m);
for(i=n-1;i>=n-m;i--)
|cout<<a[i];
|if(i>n-m){
||cout<<" ";

函数代码

#include<iostream>
#include<vector>
using namespace std;
void swap(int &a,int &d){
    int k;
    k=a;
    a=d;
    d=k;
}
void tui(vector<int>&a,int n,int m)
{
    int k=m;
    int l=2*m+1;
    int r=2*m+2;
    if(l<n&&a[l]>a[k]){
        k=l;
    }
    if(r<n&&a[r]>a[k]){
        k=r;
    }
    if(k!=m){
        swap(a[m],a[k]);
        tui(a,n,k);
    }
}
void tui1(vector<int>&a,int n,int m){
    int i;
    for(i=n/2-1;i>=0;i--){
        tui(a,n,i);
    }
    for(i=n-1;i>=n-m;i--){
        swap(a[0],a[i]);
        tui(a,i,0);
    }
}
int main()
{
    int n,m,i;
    cin>>n>>m;
    vector<int>a(n);
    for(i=0;i<n;i++){
         cin>>a[i];
}
    if(n<m){
        m=n;
    }
    tui1(a,n,m);
    for(i=n-1;i>=n-m;i--){
         cout<<a[i];
        if(i>n-m){
        cout<<" ";
        }
    }
    return 0;
}

时间复杂度为nlog(n),空间复杂度为O(n)

三、实验使用环境

以下请根据实际情况编写

  • 操作系统:Windows 11专业版
  • 编程语言:C++
  • 开发工具:[Visual Stdio 2022]

四、实验步骤和调试过程

寻找大富翁

本机运行截图

运行分析

输入的第一个值是有多少人符合要求,第二个是输出人数
输出:
对于sort函数,数组已经全部排序好了,从最大到最小,输出时只要数组前m个就好
对于堆函数,要几个就排几个,并没有全部排好,求是按照最小到最到大,输出从数组最后开始输出m个

五、实验小结

遇到的问题及解决方法:

  1. 问题:判断函数逻辑有问题
  • 解决方法:修改代码

实验体会和收获:

这段C++代码用于对输入的整数数组进行排序并输出前m个最大的数。
对于sort函数(STL库自带),给它起点和终点,数组会自动排序,最后只要输出,操作简单。
对于堆排列,代码首先定义了交换函数swap和调整堆结构的函数tui,然后通过tui1函数构建最大堆并进行堆排序。
把数组看成树,奇数是左孩子,偶数是右孩子,调用tui函数来调整堆的结构,用a[m]来和其左右孩子比较,如果左(右)孩子(左孩子下标为2m+1,右孩子下标为2m+2)大于a[m],记住其下标,最后交换两个值,再递归,直到值大于左右孩子,这时堆就调整好了。
tui1函数先从前面i=n/2-1(是为了从最后一个非叶节点开始调整)进行对堆的调整排序,之后从n-1开始不断与a[0]交换,再调整堆,直到结束,对于后面m个数就排好了序。
在main函数中,读取输入数据,用vector来进行动态存储,之后调用tui1函数进行排序,并输出结果(题目要求末尾不可以有多余的空格,需要判断空格是否输出)。


posted @ 2025-05-24 22:55  穗和  阅读(11)  评论(0)    收藏  举报