题目链接https://vjudge.net/problem/UVA-815
有一个n*m(1≤m,n<30)的网格,每个格子是边长10米的正方形,网格四周是无限大的墙壁。输入每个格子的海拔高度,以及网格内雨水的总体积,输出水位的海拔高度以及有多少百分比的区域有水(即高度严格小于水平面)。
注意:Follow the output for each region with a blank line.说的是每个测试用例输出结束之后输出一个空行!!!蛋疼,之前理解成两次输出中间有一个空行,我就处理成第二次或者之后每次输出的时候先输出一个空行。这是不对的,两者之间有差别的!改了这个细节之后代码立即通过了,下次要细心了!=_=
方法一:排序之后,①算出每次填补到下一格高度需要的水的体积,用总的体积数减去当前的体积数来判断。②结束条件是填补到下一个高度时水不够或者已经填满了最高高度。
方法二:排序之后,③算出所有的水用来填补第二个格之后的高度、填补第三个格之后的高度......④结束条件是填补完当前格之后水的高度比下一个格子高度低。
方法二用了一个小技巧,在数组结尾之后加上一个数据,此数据是0x7fffffff,为有符号int型最大值。当然也可以照此思想加上一个数,把①和④组合在一起,最后判断什么时候水不够用,这样可以不用考虑所有的填满了还是没填满。
方法一代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[1000];
int main(){
int m,n,cubi,cnt=0;
while(~scanf("%d%d",&m,&n)&&m&&n){
for(int i=0;i<m*n;i++) scanf("%d",&a[i]);
scanf("%d",&cubi);
double cub=cubi*1.0/100;
sort(a,a+m*n);
//for(int i=0;i<m*n;i++) printf("%d ",a[i]);
int sum=0,i=0,last=0;
double high=0.0,percent=0.0;
for(i=1;i<m*n&&(cub-sum)>0;i++){
last=sum;
sum+=i*(a[i]-a[i-1]);
}
//printf("%d %d %d\n",last,sum,i);
if(cub==0){high=a[0];percent=0; }
else if(i==m*n&&(cub-sum)>0){//水填满了最高海拔的格子,还有多的水
high=(cub-sum)*1.0/i+a[i-1];
percent=100;
}
else {
/*水没有填满最高海拔的格子,在中间时就不够用了。
这里用到sum的上一次结果,所以上面for循环中用了last保存。*/
high=(cub-last)*1.0/(i-1)+a[i-2];
percent=(i-1)*1.0/(m*n)*100;
}
printf("Region %d\n",++cnt);
printf("Water level is %.2f meters.\n",high);
printf("%.2f percent of the region is under water.\n\n",percent);//注意空行在最后面
}
return 0;
}
方法二代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[35*35];
int main(){
int m,n,cubi,cnt=0;
while(~scanf("%d%d",&m,&n)&&m&&n){
for(int i=0;i<m*n;i++) scanf("%d",&a[i]);
sort(a,a+m*n);
a[m*n]=0x7fffffff;
scanf("%d",&cubi);
double sum=cubi/100.0;
int i=0;
for(i=1;i<=m*n;i++){
sum+=a[i-1];
if(sum/i<=a[i]) break;
}
printf("Region %d\n",++cnt);
printf("Water level is %.2lf meters.\n",sum/i);
printf("%.2lf percent of the region is under water.\n\n",i*100.0/(m*n));
}
}