此题作者建议使用多种方法解题锻炼一下
我想到了若干解法,基本大同小异,真正核心的计算海拔的算法只想出两种:
第一个解法:把所有格子按海拔顺序排序,把每一档海拔与下一档之间能够容纳的水依次累加直到大于水的总体积。
第二个解法:把所有格子按海拔顺序排序,逐个计算含水海拔,第n个格子的含水海拔=(总水量+n个格子相对于0海拔的体积)/n个格子的面积和,顺序读入后面格子海拔,如果此格高于已算出的含水海拔则终止。
解法一:
//#define LOCAL
//#define TESTING
#include<stdio.h>
#include<string.h>
void swap(int* a, int* b)//变量值交换函数
{
int t = *a; *a = *b; *b = t;
}
int main()
{
#ifdef LOCAL
freopen("xt4-10.in","r",stdin);
#endif
int m,n,kase=0;
while(scanf("%d%d",&m,&n)==2&&m&&n)
{
kase++;
#ifdef TESTING
printf("%d %d\n", m, n);
#endif
int tot = m*n;//tot格子总数
int grid[tot+2],water;//grid[]格子海拔 water水量
for(int i = 1; i <= tot; i++)//读入格子海拔并顺序排序
{
scanf("%d",&grid[i]);
for(int j = i; j > 1; j--)
{
if(grid[j]<grid[j-1]) swap(&grid[j-1],&grid[j]);
else break;
}
}
scanf("%d",&water);//读入水量
#ifdef TESTING
for(int i = 1; i <= tot; i++) printf("%d ",grid[i]);
printf("\n%d\n",water);
#endif
int amt=0,gridamt = 0,totvol = 0;//amt被水淹没的格子数量 gridamt 纳入容积计算的格子数量 totvol纳入计算的容积总量
float wlevel;//wlevel最终海拔
for(int i = 1; i <= tot; i++)//从海拔最低的格子开始计算
{
gridamt=i-1;//被水淹没的格子数量
int tempvol = 0;//本轮计算的容积
int addgrid=1;//同档海拔的纳入海拔计算的格子数量
for(int j = i+1; j <= tot+1; j++)//统计本轮计算同档海拔格子数量,统计完成后计算本轮新增容积
{
if(j==(tot+1))//如果本轮所有格子都已纳入计算
{
gridamt = tot;
tempvol = water;
i=tot;
}
else if(grid[j] == grid [i]) addgrid++;//如果海拔与本轮第一个格子相等则addgrid+1
else//如果不等则计算海拔
{
gridamt+=addgrid;//将本轮增加的格子数纳入被水淹没的格子总量
tempvol = (grid[j] - grid[i])*gridamt*100;//计算本轮新增容积
#ifdef TESTING
printf("\n%d %d %d %d %d %d\n",i,grid[i],grid[j],gridamt,tempvol,totvol);
#endif
i=j-1;
break;//完成计算后跳出循环
}
}
amt = i;
if(totvol+tempvol>=water)//如果本轮总容积大于等于水量或所有格子均纳入计算
{
wlevel = grid[gridamt]+(water - totvol)/(gridamt*100.0);//计算最终海拔
#ifdef TESTING
printf("\n%d %d %d %d\n",grid[i-addgrid],water,totvol,gridamt);
#endif
break;
}
else totvol += tempvol;//如果本轮总容积小于水量且还有未纳入计算的格子,更新已计算总容积
}
#ifdef TESTING
#endif
printf("Region %d\nWater level is %.2lf meters.\n",kase,wlevel);//输出案例序号,最终海拔
printf("%.2lf percent of the region is under water.\n\n",amt*100.0/tot);//输出有水区域所占百分比
}
return 0;
}
解法二:
#include<string.h>
#include<stdio.h>
void swap(int* a, int* b)
{
int t= *a; *a = *b; *b = t;
}
int main()
{
int m,n,kase = 0;
while(scanf("%d%d",&m,&n)==2&&m&&n)
{
kase++;
int grid[m*n+1],stat[m*n+1],tot = m*n,water;
int amt=0;
float wlevel,totvol=0.0;
for(int i = 1; i <= tot; i++)
{
scanf("%d", &grid[i]);
for(int j = i; j >1; j--)
{
if(grid[j]<grid[j-1]) swap(&grid[j],&grid[j-1]);
else break;
}
}
scanf("%d", &water);
for(int i = 1; i <= tot; i++)
{
if(i==1)
{
amt++;
totvol = grid[1]*100.0;
wlevel = (water+totvol)*1.0/(100*amt);
}
else if(grid[i]<wlevel)
{
amt++;
totvol += grid[i]*100.0;
wlevel = (water + totvol)*1.0/(100*amt);
}
else break;
}
printf("Region %d\nWater level is %.2lf meters.\n", kase,wlevel);
printf("%.2lf percent of the region is under water.\n\n", amt*100.0/tot);
}
return 0;
}