Aizu-ALDS1_3_D——截面图上的区域

原题链接(OJ可提交):https://vjudge.net/problem/Aizu-ALDS1_3_D

大意是:给定一个横截面图,如果发生洪水灾害,计算并报告哪些区域会被淹没。

如图:

Aizu-ALDS1_3_D——截面图上的区域_第1张图片

用  \   /  和  _ 来模拟地形,下面的样例输入对应上图,输出中35是水的总面积,5是有5个被淹没区域。

Aizu-ALDS1_3_D——截面图上的区域_第2张图片

 这题的解题关键:水平面

如图可知,前面几个区域还是三角形,等腰梯形之类的,但到19就是不规则图形了:

Aizu-ALDS1_3_D——截面图上的区域_第3张图片

所以我们应该利用水平面的特点来解题。

水是一个平面,在这题中,想要形成水,就必须要有在同一平面上的的 ‘ \ ’ 与 ‘ / ’ 

Aizu-ALDS1_3_D——截面图上的区域_第4张图片

不用在乎下面是水还是其他,只要有同一水平面的一对,就可以形成一段区域的水。

如图所示,3和2 配对,4和1配对

Aizu-ALDS1_3_D——截面图上的区域_第5张图片 

那么转换到输入,

我们可以把输入看成一个字符串,如果遇到 ‘ / ’ 字符就往前找最近的,未配对的  ‘ \ ’ 。

说到这,应该想到用什么数据结构了吧。没错,就是栈!

Aizu-ALDS1_3_D——截面图上的区域_第6张图片

我们先遍历整个字符串,① ② 入栈,

然后遇到③,则②出栈,与③配对,计算面积。

Aizu-ALDS1_3_D——截面图上的区域_第7张图片

然后遇到 ④ ,则①出栈,与④配对,计算面积。

这样子,就可以求出总面积了。

求总面积的代码:

Aizu-ALDS1_3_D——截面图上的区域_第8张图片

理解好代码,注意此时程序对截面图的运算过程, 相当于截面图,从左往右,从下往上。记住这个顺序,接下来求各个区域会用到。

接下来,求各个区域的面积。

我们先来看两种情况:

Aizu-ALDS1_3_D——截面图上的区域_第9张图片

此时程序应该保存两个4。

Aizu-ALDS1_3_D——截面图上的区域_第10张图片 此时程序应该保存一个17。

我们刚刚说程序的运算过程是从左往右,从下往上,那么,

我们可以用一个动态数组,数组里面存放的结构体,结构体有两个元素,

Aizu-ALDS1_3_D——截面图上的区域_第11张图片

一个用来保存区域的最左边,一个用来保存该区域水的面积。

那我们如何应对上面的那种情况呢?

Aizu-ALDS1_3_D——截面图上的区域_第12张图片

由程序运算顺序可知,最上面区域水的面积,是会最晚算的,

我们此时会得到一个【0,9】(0代表最左边位置为0,9代表面积为9)的有序对。

而此时程序中已经有了下面的有序对:

Aizu-ALDS1_3_D——截面图上的区域_第13张图片

1和5都比0大,于是我们用【0,9】 覆盖【1,4】【5,4】

得到新的记录:【0,17】(9+4+4=17)

讲解完毕。

AC代码:

#include
#include
#include
#include
using namespace std;



stack s1;

struct Node
{
	int left;
	int area;
	Node(int l,int a)
	{
		left=l;
		area=a;
	}
};
vector v;//保存各区域面积

int main()
{
	string S;
	cin>>S;
	int sum=0;//字符串长度最大20000,则最大面积 < 2*10^8
	for(unsigned int i=0; ij)
			{
				a+=v.back().area;
				v.pop_back();
			}

			v.push_back(Node(j,a));
		}
	}
	cout<

Aizu-ALDS1_3_D——截面图上的区域_第14张图片

Over. 

你可能感兴趣的:(ACM,数据结构)