当前位置: 代码迷 >> 综合 >> POJ 1877 Flooded! 排序,二分
  详细解决方案

POJ 1877 Flooded! 排序,二分

热度:34   发布时间:2023-12-13 19:59:18.0

题意:
将一个区域分成r*c个方块,每个方块有有一个海拔(可正可负)。求当给区域注入指定容量的水时,水面的海拔是多少,以及被水淹没的方块占总方块数的百分比。每个方块的面积为100m^2,水的容量单位为立方米

本题要点:
1、二分查找,套 ACWing 的模板
2、考虑到有的海拔为负数,因此,全部海拔减去一个最小的海拔值, 转化为相对的海拔高度来计算
对 相对海拔高度 排序, 二分其下标

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF = 0x7fffffff;
const int MaxN = 1000;
int height[MaxN];
double level[MaxN];
int m, n; 
double h;
int minH;bool judge(int mid)
{
    double sum = 0;for(int i = 0; i <= mid; ++i)	// 累加 0 ~ mid 的所有高度{
    sum += level[i];}return sum + h / 100 < level[mid + 1] * (mid + 1);	// 不足以淹没 第 mid + 1 个 区域时候,返回 true
}void solve(int cnt)
{
    int t = n * m;for(int i = 0; i < t; ++i){
    level[i] = height[i] - minH;	// 转化为相对高度 }int left = 0, right = t - 1, mid;sort(level, level + t);while(left < right){
    mid = (left + right) / 2;//printf("left = %d, right = %d, mid = %d\n", left, right, mid);if(judge(mid)){
    right = mid;	}else{
    left = mid + 1;}}double sum = 0;for(int i = 0; i <= left; ++i){
    sum += level[i];}printf("Region %d\n", cnt);double avg = (sum + h / 100) / (left + 1) + minH; printf("Water level is %.2lf meters.\n", avg);double p = double(left + 1) * 100 / t;printf("%.2lf percent of the region is under water.\n\n", p);
}int main()
{
    int cnt = 0;while(scanf("%d%d", &n, &m) && n && m){
    minH = INF;int t = m * n;for(int i = 0; i < t; ++i){
    scanf("%d", &height[i]);minH = min(minH, height[i]);}scanf("%lf", &h);solve(++cnt);}return 0;
}/* 3 3 25 37 45 51 12 34 94 83 27 10000 0 0 *//* Region 1 Water level is 46.67 meters. 66.67 percent of the region is under water. */