【题目描述】
有nn个函数,分别为F1,F2,...,FnF1,F2,...,Fn。定义Fi(x)=Aix2+Bix+Ci(x∈N∗)Fi(x)=Aix2+Bix+Ci(x∈N∗)。给定这些Ai、BiAi、Bi和CiCi,请求出所有函数的所有函数值中最小的mm个(如有重复的要输出多个)。
【输入】
第一行输入两个正整数nn和mm。
以下nn行每行三个正整数,其中第ii行的三个数分别位AiAi、BiBi和CiCi。输入数据保证Ai≤10,Bi≤100,Ci≤10000Ai≤10,Bi≤100,Ci≤10000。
【输出】
将这nn个函数所有可以生成的函数值排序后的前mm个元素。这mm个数应该输出到一行,用空格隔开。
【输入样例】
3 10 4 5 3 3 4 5 1 7 1
【输出样例】
9 12 12 19 25 29 31 44 45 54
【提示】
【数据规模】
n,m≤10000n,m≤10000。
用堆做的时候运行错误 数组开的不够大,所以错误了
#include<bits/stdc++.h>
using namespace std;
int heap[10005];
int heap_size;
void put(int x)
{
heap[++heap_size]=x;
push_heap(heap+1,heap+1+heap_size);
}
int get()
{
pop_heap(heap+1,heap+1+heap_size);
return heap[heap_size--];
}
int f(int a,int b,int c,int i)
{
return a*i*i+b*i+c;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
for(int i=1;i<=m;i++) put(f(a,b,c,i));
for(int i=2;i<=n;i++){
scanf("%d%d%d",&a,&b,&c);
for(int j=1;j<=m;j++){
if(f(a,b,c,j)<heap[1]){
get();
put(f(a,b,c,j));
}
}
}
int s[10000];
for(int i=0;i<m;i++){
s[i]=get();
}
for(int i=m-1;i>=0;i--)
printf("%d ",s[i]);
return 0;
}
用优先队列做也可以
#include<bits/stdc++.h>
using namespace std;
priority_queue<int>heap;
int f(int a,int b,int c,int i)
{
return a*i*i+b*i+c;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
for(int i=1;i<=m;i++) heap.push(f(a,b,c,i));
for(int i=2;i<=n;i++){
scanf("%d%d%d",&a,&b,&c);
for(int j=1;j<=m;j++){
if(f(a,b,c,j)<heap.top()){
heap.pop();
heap.push(f(a,b,c,j));
}
else break;
}
}
int s[10000];
for(int i=1;i<=m;i++){
s[i]=heap.top();
heap.pop();
}
for(int i=m;i>=1;i--)
printf("%d ",s[i]);
return 0;
}