UVA815 洪水! Flooded!
题目描述

输入格式

输出格式

输入输出样例 #1
输入 #1
3 3
25 37 45
51 12 34
94 83 27
10000
0 0
输出 #1
Region 1
Water level is 46.67 meters.
66.67 percent of the region is under water.
题目大意
为方便购房者估算洪水保险费用,一家房地产公司会向客户提供待购区域内每一块 10 米 ×10 米正方形地块的海拔高度。雨水、融雪以及水管爆裂产生的水会最先汇集到海拔最低的地块,地势更高地块的水会顺势向下流淌。为简化问题,我们做如下假设:雨水管道可以让封闭山谷内高地的水流向海拔更低的地块,并且土地不会吸收水分。根据气象存档数据,我们可以获知一片区域汇集的总水量。作为潜在购房者,我们希望得知水在低洼地块汇集稳定之后的水位海拔,同时还希望知道区域中被完全淹没的面积占比,即地块海拔严格小于水位的 10 米方块所占的百分比。请你编写程序输出上述计算结果。
输入
输入有多组区域数据。每组开头两个整数 m、n(都小于 30),代表该区域有 m 行、n 列地块,单位是 10 米。之后 m 行,每行 n 个整数,按行优先给出每块地的海拔(米;正数海平面以上,负数海平面以下)。每组最后一个整数:总积水体积,单位立方米。当输入 0 0 的时候代表输入结束。
输出
对每个区域输出:区域编号(1,2,3......);水位海拔(保留两位小数);被淹没区域百分比(保留两位小数)。每组输出结束后,输出一个空行。
解题思路
先把所有地块的海拔从小到大排好序,从地势最低的地方开始蓄水,尝试把已经被水淹的地块整体抬升到下一个更高的海拔,算出抬升需要消耗多少水,如果剩下的水够用就扣掉对应的水量,继续扩大被淹没的地块数量,要是水不够,就把剩下的水平均分给当前已经淹没的地块,算出最终水位;如果所有地块全都被淹没,就把剩余的水全部摊到全部地块上算出水位,最后统计海拔严格小于水位的地块数量,算出淹没占比。
完整代码
java
import java.util.Arrays;
import java.util.Scanner;
class Region {
public int m;
public int n;
public int[] elevations;
public int waterVolume;
public double waterLevel;
public double submergePercent;
}
public class Flooded {
private static final int ONE_BLOCK_AREA = 100;
private static Region readInput(Scanner sc) {
int m = sc.nextInt();
int n = sc.nextInt();
if (m == 0 && n == 0) {
return null;
}
Region reg = new Region();
reg.m = m;
reg.n = n;
int total = m * n;
reg.elevations = new int[total];
for (int i = 0; i < total; i++) {
reg.elevations[i] = sc.nextInt();
}
reg.waterVolume = sc.nextInt();
return reg;
}
private static void processData(Region reg) {
int[] elev = reg.elevations;
Arrays.sort(elev);
int totalCells = elev.length;
double remainWater = reg.waterVolume;
int k;
double waterLevel = 0;
for (k = 1; k < totalCells; k++) {
double deltaH = elev[k] - elev[k - 1];
double needWater = k * ONE_BLOCK_AREA * deltaH;
if (remainWater >= needWater) {
remainWater -= needWater;
} else {
waterLevel = elev[k - 1] + remainWater / (k * ONE_BLOCK_AREA * 1.0);
break;
}
}
if (k == totalCells) {
waterLevel = elev[totalCells - 1] + remainWater / (totalCells * ONE_BLOCK_AREA * 1.0);
}
reg.waterLevel = waterLevel;
int cnt = 0;
for (int e : elev) {
if (e < waterLevel) {
cnt++;
}
}
reg.submergePercent = 100.0 * cnt / totalCells;
}
private static void printOutput(Region reg, int regionId) {
System.out.printf("Region %d%n", regionId);
System.out.printf("Water level is %.2f meters.%n", reg.waterLevel);
System.out.printf("%.2f percent of the region is under water.%n", reg.submergePercent);
System.out.println();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int id = 1;
while (true) {
Region region = readInput(sc);
if (region == null) {
break;
}
processData(region);
printOutput(region, id++);
}
sc.close();
}
}
测评结果
