第三部分 数据结构 -- 第三章 树-1370:最小函数值(minval)

1370:最小函数值(minval)

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 3422 通过数: 1477
【题目描述】
有n个函数,分别为F1,F2,…,Fn。定义Fi(x)=Aix2+Bix+Ci(x∈N∗)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个)。

【输入】
第一行输入两个正整数n和m。

以下n行每行三个正整数,其中第i行的三个数分别位Ai、Bi和Ci。输入数据保证Ai≤10,Bi≤100,Ci≤10000。

【输出】
将这n个函数所有可以生成的函数值排序后的前m个元素。这m个数应该输出到一行,用空格隔开。

【输入样例】
3 10
4 5 3
3 4 5
1 7 1
【输出样例】
9 12 12 19 25 29 31 44 45 54
【提示】
【数据规模】

n,m≤10000。


思路:Max-heap: 父节点的值大于或等于子节点的值;父节点的值大于或等于子节点的值,如下例子:
在这里插入图片描述
建一个大根堆,存最小的数到第m小的数,第m小的数就是堆顶,每次只需要比较新加进来的数比堆顶大还是比堆顶小,如果比堆顶小,将原来的堆顶丢掉,将新的数压入;题意,a>0 && b>0,函数对称轴x = −b / 2 ∗ a<0,==> y在x > 0时是单调递增,函数值y只会大不会小,可以直接break掉了。大根堆,要逆序输出,将m个数从小到大输出。

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
int ans[10010];
priority_queue<int,vetcor<int>,less<int> > q;
int main(){
	int n,m;
	cin >> n>> m;
	for(int i = 1; i <= n; i++){
		int a,b,c;
		cin >> a >> b >> c;
		for(int j = 1; j <= m; j++)
		{
			int k = a*j*j + b*j + c;
			if(i == 1) q.push(k);
			else
			{
				if(k < q.top()){//如果比堆顶小,将原来的堆顶丢掉,将新的数压入
				q.push(k);
				q.pop(); 
			 } 
			 else break;
		}
	}	
}
	for(int i = 1; i <= m; i++){
		ans[i] = q.top();
		q.pop();
	}
	for(int i = m ; i >= 1; i--)//大根堆,要逆序输出
	{
		cout << ans[i] <<" ";
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章