GBQC国的小明家里有N棵树,每天小明都会给其中一棵树浇水,每次浇水后,树都会长高一些,但由于树的品种不同,每次增长的高度也有所区别。
为了使这N棵树看起来整洁、美观,小明希望最高的树和最低的树的高度差越小越好。现在小明想知道,如果至多浇K次水,最高的树和最低的树的高度差最小为多少?
输入包含多组测试数据。
对于每组测试数据,第一行包含两个正整数N(2<=N<=10^5)、K(1<=K<=10^5),含义同上。接下来一共有N行,每行有两个正整数h(1<=h<=10^3)、d(1<=d<=10^3),分别描述了这N棵树的初始高度,以及每次浇水后这棵树增长的高度。
对于每组测试数据,用一行输出一个整数表示如果小明至多浇K次水,最高的树和最低的树的高度差最小为多少。
由于数据量较大,推荐使用scanf和printf。
比赛的时候自己没有座出来 好多队员都做出来了 自己要加油了啊
思路 贪心
每次要浇水肯定浇最矮的那棵树,只有这样才能保证最小的差值。
同学代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; struct qu { int id; int v; bool operator <(const struct qu &tem)const { return id>tem.id; } }; priority_queue <qu> que; int ss[100010][2]; int n,m; int main() { int i,max,min; while(scanf("%d%d",&n,&m)!=EOF) { max=-1; for(i=1;i<=n;i++){ scanf("%d%d",&ss[i][0],&ss[i][1]); if(ss[i][0]>max)//找到最大值 max=ss[i][0]; } while(!que.empty())que.pop();//清空队列 qu tem; for(i=1;i<=n;i++){//所有元素入队列 tem.id=ss[i][0]; tem.v=ss[i][1]; que.push(tem); } int ans=999999999; for (i=0;i<=m;i++) { qu tt; tem=que.top();//最小元素出队列 que.pop(); min=tem.id; if(ans>max-min)ans=max-min;//更新最小值 if(ans==0)break;//最小差为0 ,退出 tt.id=tem.id+tem.v;//更新原本最小树的高度 tt.v=tem.v; if(tt.id>max)max=tt.id;//更新最大值 que.push(tt);//原本最小树更新完后入队列 } printf("%d\n",ans); } return 0; }