题目描述
有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
//那么来说一下这道题的玄学思路,原先我就是简单的做了一个n套m的循环然后堆排,结果只过了两个点其余全都tle。但若要计算每一个函数的可能值必定要n*m,顿觉无解
//但是,那么问题来了(敲黑板),我们并不一定枚举每个函数的值,我把每个函数都求了下x=1时的值,然后用结构体存下函数组数与函数x=1时的值。处理排序时,先找出x=1时函数值最小的值(普通sort)并命名为syq是dalao函数,把其余函数命名为zfh是蒟蒻函数。然后给x值++并带入syq是dalao函数,放入堆中并对比其余zfh是蒟蒻函数x=1时的值,堆排,最后速度会很快,大概只有60ms左右,内存也只有2mb,而原来的方案却是12000ms与300mb的时复与空复,所以解法的确很烧脑很玄学
//上代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=10005;
int n,m,a[maxn],b[maxn],c[maxn];
int f[maxn];//f会一直++,带入x=1时最小的函数
struct EA{
int data;
int nm;
}x[maxn];
int cmp(EA f1,EA f2){
return f1.data<f2.data;
}
int main(){
for(int i=1;i<=10000;i++)
f[i]=2;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i]>>c[i];
x[i].data=a[i]+b[i]+c[i];
x[i].nm=i;//组数
}
sort(x+1,x+n+1,cmp);
for(int i=1;i<=m;i++){
cout<<x[1].data<<" ";//找到x=1时最小的函数,命名为syq是dalao函数,其余函数都命名为zfh是蒟蒻函数
int g=x[1].nm;//g是函数组数
x[1].data=f[g]*a[g]*f[g]+b[g]*f[g]+c[g];//f一直++并带入syq是dalao函数
f[g]++;
int t=1;
while(t*2<=n){//看余下zfh是蒟蒻函数在x=1时其中有无带入比当前syq是dalao函数的值还小
int tp=t*2;
if(tp+1<=n&&(x[tp+1].data<x[tp].data)) tp++;//堆排
if(x[tp].data<x[t].data){
EA kx=x[tp];//有就交换
x[tp]=x[t];
x[t]=kx;
t=tp;
}//if
else break;
}//while
}//for
return 0;
}