中南OJ 2012年8月月赛 H题 Happy watering

  中南大学OJ 2012年8月月赛,H题,Happy watering题目链接)。

Problem H: Happy watering

Description

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

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

Input

  输入包含多组测试数据。

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

Output

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

Sample Input

2 1
7 2
10 3

2 4
7 2
10 3

2 3
7 8
10 9

Sample Output

1
0
3

Hint

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

  解题思路:使用C++中的STLmultiset来储存树木的自身高度和每次浇水长高的高度。按照自身高度排序。每次取出最矮的,浇一次水。浇水同时,循环打擂求最小极差。求极差的方法:每次都把最高的树(即multiset中的最后一个元素)的高度,减去最矮的树(即multiset中的第一个元素)的高度,即为极差。最终输出最小极差即可。

  C++语言源代码如下:

#include <cstdio>
#include <cstdlib>
#include <set>
#include <climits>

using namespace std;

typedef int COUNT;

class tree_property
{
    public:
        int height;
        int grown_per_water;
        bool operator<(const tree_property & tree ) const
        {
            return height < tree.height;
        }
};

void read_data( multiset <tree_property> & ordered_trees, const int tree_count )
{
    tree_property tree;
    for ( COUNT i = 0 ; i < tree_count ; i ++ )
    {
        scanf( "%d%d", &(tree.height), &(tree.grown_per_water) );
        ordered_trees.insert(tree);
    }
}

int water_tree( multiset <tree_property> & trees, const int tree_count, const int max_water )
{
    int range, min_range;
    tree_property shortest_tree;

    multiset <tree_property>::iterator shortest_tree_iterator;
    multiset <tree_property>::iterator tallest_tree_iterator;

    shortest_tree_iterator = trees.begin();
    tallest_tree_iterator = trees.end();
    tallest_tree_iterator --;

    min_range = range = tallest_tree_iterator->height - shortest_tree_iterator->height;

    for ( COUNT i = 0 ; i < max_water ; i ++ )
    {
        shortest_tree_iterator = trees.begin();
        shortest_tree = (*shortest_tree_iterator);
        trees.erase( shortest_tree_iterator );
        shortest_tree.height += shortest_tree.grown_per_water;
        trees.insert( shortest_tree );

        shortest_tree_iterator = trees.begin();
        tallest_tree_iterator = trees.end();
        tallest_tree_iterator --;

        range = tallest_tree_iterator->height - shortest_tree_iterator->height;
        if ( range < min_range )
            min_range = range;
    }
    return min_range;
}

void test_case( const int tree_count, const int max_water )
{
    multiset <tree_property> trees;
    read_data( trees, tree_count );
    printf( "%d\n" , water_tree( trees, tree_count, max_water ) );
}

int main (void)
{
    int tree_count, max_water;
    while ( scanf( "%d%d", &tree_count, &max_water ) != EOF )
    {
        test_case( tree_count, max_water );
    }
    return EXIT_SUCCESS;
}
posted @ 2012-08-12 17:46  叶剑飞Victor  阅读(387)  评论(0编辑  收藏  举报