C语言日记21.12.15-16

字数:1082访问原帖 评论数:2条评论 TXT下载

发表时间:2021-12-17 07:52:42 更新时间:2021-12-27 07:25:36

楼主:ty_144568977  时间:2021-12-16 23:52:42
题目:积水
给出数组,数组中的数代表该位置“柱子”的高度;求“柱子”之间的最大积水量。
//参考泰拉瑞亚的积水方式

思路:
遍历数组,找“洼地的最低点”(a[i-1]>=a[i]<=a[i+1]);
从洼地开始,分别向左、右求“容器壁”,记录高度和位置;
判断左右壁的高度,取高度小的;
以这个高度计算左、右壁之间的水深,相加即为“洼地”积水量;

注意:(卡了很久的点)

*求“容器壁”部分
1. 对于第一个洼地,向左求最大值,再向右求值,取第一个大于等于左值的值(防止错误划分洼地);
2. 对于之后的洼地,向左求最大值时,在上一个洼地的右壁处停止(防止重复计算);

*求水深
1. 一个洼地里,只有深度低于水面高度的部分才会积水;

*初始值
对于每一个洼地最低点a[i],左位置设为i,左右壁的高度设为a[i],右位置在计算出新的左值后设为i;
积水量初始设为0,在函数内累加;

*其他
如果函数在Dev上带不动,就写一个功能和变量形式(指针)一样的main函数,在DEV上测试;
数学类(?)的题目记得画图,多试几种可能性;

参考代码:
//函数的输入是指针*a,所以函数内的操作都用指针形式;

int i,j,cnt1=0,cnt2=0,left,right;
int water=0;
int max;

for(i=1;i<n-1;i++)
{



if(*(a+i-1) >= *(a+i) && *(a+i+1) >= *(a+i))
{
left = *(a+i); right = *(a+i); max=*(a+i); cnt1=i;
for(j=i-1;j>=cnt2;j--)
{

if(left<*(a+j))
{
left = *(a+j);
cnt1 = j;
}

}

cnt2=i;

for(j=i+1;j<n;j++)
{

if(right<=*(a+j))
{
right = *(a+j);
cnt2 = j;
if(right>=left)
break;
}
}

if(left>right)
max=right;
else
max=left;

for(j=i;j>cnt1;j--)
{
if(max>*(a+j))
water += max - *(a+j) ;
}

for(j=i;j<cnt2;j++)
{
if(max>*(a+j))
water += max - *(a+j) ;
}
water += *(a+i)-max;

i = cnt2;
}

}

--------------------------------------------------
TOP↑