题目描述
有n个函数,分别为F1,F2,...,Fn。定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个)。
输入输出格式
输入格式:
输入数据:第一行输入两个正整数n和m。以下n行每行三个正整数,其中第i行的三个数分别位Ai、Bi和Ci。Ai<=10,Bi<=100,Ci<=10 000。
输出格式:
输出数据:输出将这n个函数所有可以生成的函数值排序后的前m个元素。这m个数应该输出到一行,用空格隔开。
输入输出样例
输入样例#1: 复制
3 10 4 5 3 3 4 5 1 7 1
输出样例#1: 复制
9 12 12 19 25 29 31 44 45 54
说明
数据规模:n,m<=10000
解题思路
因为a,b,c,x都是正整数,所以,对于同一个函数,x越小,函数值越小。最小的函数值必然是当所有函数的x都为1,即所有函数的x都最小时,其函数值的最小值。将这些值存入优先队列,取出其最小值,然后将其最小值所对应的函数的x加一后的值存入优先队列。一直重复这个步骤,直到取出了最小的m个值。
代码如下
#include <iostream>
#include <queue>
#include <fstream>
#define maxn 10005
using namespace std;
struct node{
int x, sum;
node(int x, int sum): x(x), sum(sum){ }
bool operator<(const node& a)const{
return sum > a.sum;
}
};
int t[maxn];
int a[maxn], b[maxn], c[maxn];
int main()
{
//ifstream fy("testdata.in");
int n, m;
while(cin >> n >> m){
priority_queue<node> que;
for(int i = 1; i <= n; i ++){
cin >> a[i] >> b[i] >> c[i];
t[i] = 1;
que.push(node(i, a[i] + b[i] + c[i]));
}
int cnt = 0;
bool first = true;
int last = -1;
while(true){
node top = que.top();
que.pop();
cnt ++;
if(cnt > m)
break;
if(first)
first = false;
else
cout << " ";
cout << top.sum;
int x = top.x;
t[x] ++;
que.push(node(x, a[x] * t[x] * t[x] + b[x] * t[x] + c[x]));
last = top.sum;
}
cout << endl;
}
return 0;
}