zoukankan      html  css  js  c++  java
  • 中南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;
    }
  • 相关阅读:
    GYM 101572C(模拟)
    GYM 101572A(单调队列优化dp)
    Codeforces 183C(有向图上的环长度)
    Codeforces 183A(坐标系性质)
    2019湘潭校赛 G(并查集)
    2019湘潭校赛 H(dp)
    2019湘潭校赛 E(答案区间维护)
    Codeforces 1141F2(贪心、预处理)
    Codeforces Round #411(Div. 2)——ABCDEF
    基数排序学习
  • 原文地址:https://www.cnblogs.com/yejianfei/p/2635276.html
Copyright © 2011-2022 走看看