中南大学2012年8月月赛 H题 Happy watering 贪心算法

Problem H: Happy watering

Time Limit: 1 Sec  Memory Limit: 16 MB
SUBMIT: 64  Solved: 32
[SUBMIT] [STATUS]

Description

GBQC国的小明家里有N棵树,每天小明都会给其中一棵树浇水,每次浇水后,树都会长高一些,但由于树的品种不同,每次增长的高度也有所区别。

为了使这N棵树看起来整洁、美观,小明希望最高的树和最低的树的高度差越小越好。现在小明想知道,如果至多浇K次水,最高的树和最低的树的高度差最小为多少?

Input

输入包含多组测试数据。

对于每组测试数据,第一行包含两个正整数N(2<=N<=10^5)、K(1<=K<=10^5),含义同上。接下来一共有N行,每行有两个正整数h(1<=h<=10^3)、d(1<=d<=10^3),分别描述了这N棵树的初始高度,以及每次浇水后这棵树增长的高度。

Output

对于每组测试数据,用一行输出一个整数表示如果小明至多浇K次水,最高的树和最低的树的高度差最小为多少。

Sample Input

2 17 210 32 47 210 32 37 810 9

Sample Output

103

HINT

    由于数据量较大,推荐使用scanf和printf。


比赛的时候自己没有座出来 好多队员都做出来了 自己要加油了啊

思路 贪心 

每次要浇水肯定浇最矮的那棵树,只有这样才能保证最小的差值。

先把输入的数据存到优先队列中,在输入的时候找到最大值。
循环k次,每次从有限队列中找到最小的,更新之后再放入优先队列。
如果差值为0或完成k次循环退出来。

同学代码:

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



你可能感兴趣的:(算法,struct,测试,input,output)