1. 程式人生 > >空地上樹立的n個木板最多可以擋住多少單位的水

空地上樹立的n個木板最多可以擋住多少單位的水

個人說明:本題目為某公司線上筆試題,未經過實測!萬能的網友博友如果發現任何錯誤或者更好方法,請及時留言,本人好儘快刪修!

原題敘述:空地上樹立這n個從左到右的木板,它們可以把水擋住,但溢位最邊上的木板的水會流到空地上,已知每個木板的間距都是單位1,現在給定每個木板的高度,請求出總共能接住的水量。說明一點,這裡只考慮間距和高度,不考慮第三個維度,所以水量是平方單位。

示例:木板高度是2,1,3,那麼接住的水量就是2*2=4,中間的木板被淹沒;木板高度是2,4,3,則藉助的水量是2*1+3*1=5

輸入描述:第一行輸入正整數T,表示T個測試樣例,對於每個測試樣例,輸入正整數n(n<1e5),表示n個木板,接下來輸入n個正整數,表示木板高度h(h<1e4)

輸出描述:輸出T行,每一行輸出一個正整數,表示該樣例能接住的最大水量!

示例輸入:

2

3

2 1 3

3

2 4 3

示例輸出:

4

5

#include <stdlib.h>
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;

#define MIN(a,b) (a<b?a:b)

int fun(vector<int> &in)
{
	int L = 0;//左端標記
	int RM = -1;//左端標記右方最大編號
	int LV = 0;//左端標記高度
	int RMV = 0;//左端標記右方最大高度
	int i = 1;
	int size = (int)in.size();
	LV = in.at(0);
	int out = 0;
	while(i < size)
	{
		int v = in.at(i);
		if (v > LV)
		{//直接計算L到i的出水量並相加
			out += (MIN(LV, v)*(i-L));
			L = i;//更改左端標記
			LV = v;
			RMV = 0;//置零
		}
		else
		{//如果當前值不大於LV
			if (v > RMV)
			{//檢查並更改最大值
				RMV = v;
				RM = i;
			}
			if (i == (size - 1))
			{//右側的高度只能是比LV小能儲存多少水完全取決RMV
				i = RM;
				out += (RMV*(RM-L));
				L = RM;
				LV = RMV;
				RMV = 0;
			}
		}
		i++;
	}
	return out;
}

int main()
{
	int N = 0;
	cin >> N;
	vector<int>vec;//儲存n個結果
	for (int i = 0; i < N; i++)
	{
		int num = 0;
		cin >> num;
		vector<int>input;
		for (int j = 0; j < num; j++)
		{
			int tn = 0;
			cin >> tn;
			input.push_back(tn);
		}
		int out = fun(input);
		vec.push_back(out);
	}
	for (int i = 0; i < N; i++)
	{
		cout << vec.at(i) << endl;
	}
	system("pause");
	return 0;
}