UVa 815 Flooding!(排序)

来源:互联网 发布:淘宝卖家后台网址 编辑:程序博客网 时间:2024/06/11 08:17

原题地址

https://vjudge.net/problem/UVA-815

题意:有一个n*m的方格,每个格子的底面都是边长为10的正方形,整个区域外看作无限高的墙壁。输入每个格子的海拔高度,以及区域内的雨水总体积,输出区域水位的海拔高度以及淹没方格的占比。

解题思路

本题是《算法竞赛入门经典》的习题4-10,这一章前面几道习题都比较复杂,为了照顾到后面的进度,先跳过啦。

刚开始没有读懂题意,后来看了网上对题目的解释,才懂了这个海平线高度是什么意思——每个方格的海拔相当于这个方格的固体体积,可以把它们都看作木块,雨水只存在两个木块间高度差的空间内。从正视图看相当于3D的柱状图啦。

小图

假设我们现在正在处理橙色的方格i,从上一个蓝色柱子i-1顺利上升到这个橙色柱子,就要使得剩余的水量超过(i-1的高度*i之前的方格数),不然得话,只能在i-1的高度上均匀上升(剩余水量平摊到之前每个方格)。扫描升序后的序列,要么停在某两个高度之间,要么能淹没整个大区域绰绰有余。

需要注意的是

  • 由于每个方格底面积相同,为了简化问题可以把雨水量/100,转化为对高度做处理(思想还是记住体积的思想哈)。
  • int和double的小问题,注意int*1.0转为double

AC代码

#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;int main(){    int n, m, kase = 0;    int cube[1000];    while (cin >> n >> m && n)    {        kase++;        n *= m;        for (int i = 0; i < n; ++i) //读入每个方格的高度            cin >> cube[i];        double left; //声明为int后面加1.0,避免麻烦声明为double        cin >> left;        sort(cube, cube+n); //高度升序        left /= (10*10); //体积转化为高度,之后都对高度处理        double height, percent;        for (int i = 1; i < n; ++i)        {            double diff = (cube[i] - cube[i-1]) * i; //从上个海平线升至当前海平线需要的体积差            if (left >= diff) //能淹没到当前海平线                left -= diff;            else //无法淹没当前海平线,只能对上一个高度均匀上升            {                height = cube[i-1] + left/i; //最终高度                left = 0; //清空                percent = i*1.0/n; //所有淹没方格的占比,注意乘1.0                break;            }        }        if (left != 0) //淹没所有地平线仍有多余        {            height = cube[n-1] + left/n;            percent = 1.0;        }        printf("Region %d\n", kase);        printf("Water level is %.2f meters.\n", height);        printf("%.2f percent of the region is under water.\n\n", percent*100);    }    return 0;}
0 0