无意中看到一个挺好玩的题目,尝试做了一下。也算是对现在自己编码水平的一个记录。
题目
看下面这个图片”
“在这个图片里我们有不同高度的墙。这个图片由一个整数数组所代表,数组中每个数是墙的高度。上边的图可以表示为数组[2,5,1,2,3,4,7,7,6]”
“假如开始下雨了,那么墙之间的水坑能够装多少水呢?”
“以1×1的方块为单位计算容积。所以,在上边的图中下标为1以左的都会漏掉。下标7以右的也会漏掉。剩下的只有在1和6之间的一坑水,容积是10”
我的代码
#include<iostream>
#include<cstring>
using namespace std;
const int N=10;
int wall[N]={2,5,1,2,3,4,7,7,6};
//如果想要存住水,则需要一个墙不低于左右墙的值。
//因此首先find_peak来寻找峰值,peak[]中存储的是wall的角标。
void find_peak(int wall[],int peak[])
{
int count=0;
if(wall[0]>wall[1]) peak[count++]=0;
for(int i=1;i<N-1;i++)
{
if(wall[i-1]<=wall[i]&&wall[i+1]<=wall[i])
peak[count++]=i;
}
if(wall[N-1]>wall[N-2]) peak[count++]=N-1;
}
//接下来计算水容量。仅在两个峰之间才会出现水。
int calcu_water(int left,int right)
{
int volumn=0;
int board=(wall[left]<=wall[right])?wall[left]:wall[right];
//两个峰,水位最高为较低的峰值,定义为board
for(int i=left;i<=right;i++)
{
if(wall[i]<=board)
volumn+=(board-wall[i]);
//高于board的墙不会存水,不计算。
}
return volumn;
}
int water(int *a)
{
int peak[N],i=0,volumn=0;
memset(peak,-1,sizeof(peak));
find_peak(wall,peak);
while (peak[i+1]>=0)
{
volumn+=calcu_water(peak[i],peak[i+1]);
i++;
}
return volumn;
}
int main()
{
cout<<water(wall);
getchar();
}
问题——
<span style="color: rgb(17, 17, 17); font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12.8000001907349px; line-height: 18.7199993133545px; background-color: rgb(255, 255, 255);">1.peak[]的引入,在wall[]很大时,会占用存储空间。考虑使用链表记录peak值。</span>
2.wall[]要遍历一次,然后确定peak后还要遍历一次,可不可以一遍完成?
突然想到,如果在寻找到一个峰的时候记录当前值,然后去寻找下一个峰,完全可以避免建立peak数组,只需要额外两个标记点即可。显然这么做更加效率一些。
不过大致过程差别不大。
现在风格大致就是这样了,将来回头看看有没有进步。