题目:有一个n*m(1<=m,n<30)的网格,每个格子是边长10m的长方形,网格四周是无限大的墙壁。输入每个格子的海拔高度,以及网格内雨水的总体积,输出水位的海拔高度以及有多少百分比的区域有水(即高度严格小于水平面)。
思路:由于水位的海拔高度的范围是确定的,网格内的雨水总体积确定。因此可以用二分查找法来枚举水位的海拔高度。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
int m,n,high[31][31],sum,tot=0,lowest_level[31][31],max_h,min_h;
int check(double h){
double V=0;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
if(h>high[i][j]) V+=(h-high[i][j])*100;
if(V-sum>0) return 1;
else return 0;
}
int main(){
cin>>m>>n;
while(m!=0&&n!=0){
tot++;
printf("Region %d\n",tot);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&high[i][j]);
min_h = high[1][1];
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
if(high[i][j]<min_h) min_h = high[i][j]; //海平面的最低值
cin>>sum;
double left = min_h,right = 1000000000;
while(right-left>=1e-8){ //二分查找海平面高度
double mid = (left+right)/2.0;
if(check(mid)) right = mid;
else left = mid;
}
int num=0;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++) if(high[i][j]<right) num++; //高度严格小于水平面的数目
printf("Water level is %.2f meters.\n",right);
printf("%.2f percent of the region is under water.\n\n",double(num)*100.0/(1.0*n*m));
cin>>m>>n;
}
return 0;
}