有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
思路:这道题和上篇博客一样,属于求最小前m数问题,使用堆来解决,但是,在写这个题的时候10个点有8个点内存超限,让我对这个容器的使用产生了一定的困扰。因为是维护m个数,所以第m+1大以后的数都是无效数据,但我在使用时没有对容器进行空间释放,然后就超内存了。(ps:题目样例有问题)
代码如下:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<set>
#include<string.h>
#include<queue>
#include<math.h>
#define per(i,a,b) for(int i=a;i<=b;++i)
#define inf 0xf3f3f3f
#define rep(i,a,b) for(int i=a;i>=b;--i)
#define ll long long
using namespace std;
/*const int MAXBUF=10000;
char buf[MAXBUF],*ps=buf,*pe=buf+1;
inline void rnext()
{
if(++ps==pe)
pe=(ps=buf)+fread(buf,sizeof(char),sizeof(buf)/sizeof(char),stdin);
}
template<class T>
inline bool in(T &ans)
{
ans=0;
T f=1;
if(ps==pe) return false;
do{
rnext();
if('-'==*ps) f=-1;
}while(!isdigit(*ps)&&ps!=pe);
if(ps==pe) return false;
do
{
ans=(ans<<1)+(ans<<3)+*ps-48;
rnext();
}while(isdigit(*ps)&&ps!=pe);
ans*=f;
return true;
}*/输入挂
int s[10005];
//priority_queue<int,vector<int>,greater<int>>q;
priority_queue<int>q;
int main()
{
int n,m,a,b,c;
scanf("%d%d",&n,&m);
per(i,1,n)
{
scanf("%d%d%d",&a,&b,&c);
if(q.size()<m)
{
per(j,1,n) q.push(a*j*j+b*j+c);
}else{
per(j,1,n)
{
int z=a*j*j+b*j+c;
if(z>=q.top()) break;
else q.push(z),q.pop();//释放空间
}
}
}
int k=0;
per(i,1,m)
{
int z=q.top();
s[i]=z;
q.pop();
}
rep(i,m,1) printf("%d ",s[i]);
return 0;
}