输入一个长度为n的整数数列,从小到大输出前m小的数。
输入格式
第一行包含整数n和m。
第二行包含n个整数,表示整数数列。
输出格式
共一行,包含m个整数,表示整数数列中前m小的数。
数据范围
1≤m≤n≤105,
1≤数列中元素≤109
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n, m;
int h[N], cnt;//h[N]表示堆,cnt表示总数。
void down(int x)//将x往下调整
{
int t = x;
if(2 * x <= cnt && h[2 * x] <= h[t]) t = x * 2;//左儿子存在且小于
if(2 * x + 1 <= cnt && h[2 * x + 1] <= h [t]) t = x * 2 + 1;//右儿子存在且小于
if(t != x)
{
swap(h[x], h[t]);
down(t);
}
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++) cin >> h[i];
cnt = n;
for(int i = n / 2; i; i --) down(i);//将数组变为堆
while(m --)
{
printf("%d ", h[1]);//输出根节点为当前堆中最小
h[1] = h[cnt --];//删除最小值
down(1);//进行down操作
}
return 0;
}//来自acwing