2019深信服校招——木板接水

2019深信服校招——木板接水

题目描述

       空地上竖立着n个从左到右排列的木板,它们可以把水挡住,但溢出最边上木板的水将会流到空地上。已知木板间距都是单位1,现给定每个木板的高度,请求出总共能接住的水量?说明一点,这里只考虑间距(宽度)和高度,不考虑第三个维度,因此水量是平方单位。  

       示例1,木板高度分别是2,1,3,那么我们可以接住2*2=4平方单位的水,如下图所示。注意,中间那个木板被水淹没了。

       示例2,木板高度分别是2,4,3,那么可以接住2*1+3*1=5平方单位的水,如下图所示。

思路:不断降低所有木板高度 (如图)

       (1) 先找到左右两端木板高度的较小值minHeight=min(ivec[0],ivec[size-1]) (ivec中存放排列的木板高度),求出这部分容量volume=(size-1)*miniHeight;

       (2) 将所有木板长度减去minHeight,得到新的排列木板序列,定义两个指针low、high,分别从左右开始遍历数组ivec,找到左右两端第一个高度大于0的木板,此时minHeight=min(ivec[low],ivec[high]), volume=(high-low)*minHeight;故总共能接住的总量sum += volume;(每次容量相加)

       (3) 重复步骤2,直至木板序列中只有一块木板高度大于0或全部木板高度均小于0,则此时sum为最大容量。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void sub(vector<int> &ivec, int &height)
{
	for (auto &m : ivec)
		m -= height;
}

int getVolume(vector<int> &ivec, int &low, int &high, int &height)
{
	int size = ivec.size();
	int volume = 0;
	for (; low < size; low++)
	{
		if (ivec[low]>0)
			break;
	}
	for (; high >= 0; high--)
	{
		if (ivec[high]>0)
			break;
	}
	if (low < size && high < size)
	{
		height = min(ivec[high], ivec[low]);
		volume = (high - low)*height;
	}
	return volume;
}

int main()
{
	int t;
	cin >> t; 
	while (t--)
	{
		int n;
		cin >> n;
		vector<int> ivec(n, 0);
		for (auto &m : ivec)
			cin >> m;
		int sum = 0;
		int size = ivec.size();
		int low = 0; 
		int high = size - 1;
		int height = min(ivec[low], ivec[high]);
		int volume = getVolume(ivec, low, high, height);
		while (low < size && high < size && ivec[low] > 0 && ivec[high] > 0)
		{
			sum += volume;
			sub(ivec, height);
			volume = getVolume(ivec, low, high, height);
		}
		cout << sum << endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值