【SSL】1411最小函数值
Time Limit:1000MS
Memory Limit:65536K
Description
问题描述:有n个函数,分别为F1,F2,…,Fn。定义Fi(x)=Aix^2+Bix+Ci
(x∈N*)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个)。
Input
输入数据:第一行输入两个正整数n和m。以下n行每行三个正整数,其中第i行的三个数分别位Ai、Bi和Ci。Ai<=10,Bi<=100,Ci<=10 000。
Output
输出数据:输出将这n个函数所有可以生成的函数值排序后的前m个元素。这m个数应该输出到一行,用空格隔开。
Sample Input
3 10
4 5 3
3 4 5
1 7 1
Sample Output
9 12 12 19 25 29 31 44 45 54
Hint
数据规模:n,m<=10 000
思路
m为正整数。
先把x=1入队
出队输出,
把x+1再入队
代码
#include<iostream>
#include<cstdio>
using namespace std;
const int maxlenth=10010;
struct jgt
{
int s,x,ip;
};
int a[10010],b[10010],c[10010];
class heap
{
private:
jgt h[maxlenth];
int len;
void up(int x);//上移操作,把h[x]上移的合适位置
void down(int x);//下移操作,把h[x]下移的合适位置
bool cmp(int x,int y);//若x比y优,return 1,若y比x优,return 0
public:
void init();//初始化,len=0
void swap(jgt &t1,jgt &t2);//交换两数
void build(int x);//建堆
void sort();//堆排序
void del(int x);//删除操作,删除h[x]
void push(jgt x);//插入操作,把x加入堆的合适位置
jgt top();//返回堆顶的值
void pop();//删除堆顶
bool empty();//判断堆是否空
int size();//返回堆的长度
};
void heap::init()
{
len=0;
return;
}
bool heap::cmp(int x,int y)//若x比y优,return 1,若y比x优,return 0
{
return h[x].s<h[y].s;
}
void heap::swap(jgt &t1,jgt &t2)//交换两数
{
jgt t=t1;
t1=t2,t2=t;
return;
}
void heap::up(int x)//上移操作,把h[x]上移的合适位置
{
if(x>len)return;
for(;x>1;x>>=1)
if(cmp(x,x>>1)) swap(h[x],h[x>>1]);
else return;
return;
}
void heap::down(int x)//下移操作,把h[x]下移的合适位置
{
if(x<1)return;
for(x<<=1;x<=len;x<<=1)
{
x+=(x+1<=len&&cmp(x+1,x));
if(cmp(x,x>>1)) swap(h[x>>1],h[x]);
else return;
}
return;
}
void heap::push(jgt x)//插入操作,把x加入堆的合适位置
{
h[++len]=x;
up(len);
return;
}
void heap::del(int x)//删除操作,删除h[x]
{
if(x<1||x>len)return;
if(cmp(len,x)) h[x]=h[len--],up(x);
else h[x]=h[len--],down(x);
return;
}
void heap::sort()//堆排序
{
for(;len;h[1]=h[len--],down(1))
{
//a[i]=h[1];
printf("%d",h[1].s);
}
return;
}
void heap::build(int x)//建堆
{
int i;
for(len=0,i=1;i<=x;i++)
{
//h[++len]=a[i];
scanf("%d",&h[++len].s);
up(len);
}
return;
}
jgt heap::top()//返回堆顶的值
{
jgt tem;
if(empty())//堆为空
return tem;//崩溃
return h[1];
}
void heap::pop()//删除堆顶
{
del(1);
return;
}
bool heap::empty()//判断堆是否空
{
return !len;
}
int heap::size()//返回堆的长度
{
return len;
}
int main()
{
int n,m,i;
jgt tem;
heap h;
h.init();//初始化,len=0
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
tem.s=a[i]+b[i]+c[i];
tem.x=1;
tem.ip=i;
h.push(tem);
}
for(;m--;)
{
tem=h.top();
h.pop();
printf("%d ",tem.s);
tem.x++;
tem.s+=b[tem.ip]+((tem.x<<1)-1)*a[tem.ip];
h.push(tem);
}
return 0;
}