P1318 积水面积
题目描述
一组正整数,分别表示由正方体迭起的柱子的高度。若某高度值为x,表示由x个正立方的方块迭起(如下图,0<=x<=5000)。找出所有可能积水的地方(图中蓝色部分),统计它们可能积水的面积总和(计算的是图中的横截面积。一个立方体的位置,为一个单位面积)。
如图:柱子高度变化为 0 1 0 2 1 2 0 0 2 0
图中蓝色部分为积水面积,共有6个单位面积积水。
输入输出格式
输入格式:
两行,第一行n,表示有n个数(3<=n<=10000)。第2行连续n个数表示依次由正方体迭起的高度,保证首尾为0。
输出格式:
一个数,可能积水的面积。
输入输出样例
输入样例#1:
10
0 1 0 2 1 2 0 0 2 0
输出样例#1:
6
program df;
var i,j,n,m,x,y,z,k,t:longint; ff:boolean;
a,c,d:array[0..100000] of longint;
begin
readln(n);
for i:=1 to n do
read(a[i]);
t:=0; c[0]:=0; k:=0;
for i:=2 to n-1 do
begin
z:=i;
while (t>1) and (a[i]>a[c[t]]) do //维护单调递减的栈
begin
if (a[i]>a[c[t-1]]) and (a[c[t-1]]>a[c[t]]) then
k:=k+(a[c[t-1]]-a[c[t]])*(i-d[t])
else
if (a[c[t-1]]>=a[i]) and (a[c[t-1]]>a[c[t]]) then //选取左右两端较小的一端当做高度
k:=k+(a[i]-a[c[t]])*(i-d[t]);
dec(t);
if a[c[t]]>a[i] then z:=c[t]+1; //当前的左端点
end;
inc(t);
c[t]:=i;
d[t]:=z; //记录当前的左端的位置,因为c[t] 表现的不一定是左端,a[c[t]]表达的是与左端相同的值,用d[t]记录
end;
writeln(k);
end.
浙公网安备 33010602011771号