P2085 最小函数值(堆排序)

有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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值