您的位置:首页 > 其它

(初中OJ)2242. 【2017.11.25普及组模拟】Bob

2017-11-29 20:23 204 查看
好吧,我知道我很久没单独写题解了。

Description

不但奶牛想建造房子,作为一名建筑师的Bob也想建造自己的房子。他买了块土地,问题是土地的地形不平整。

这块土地的形状就像一个矩形,长N米,宽M米。我们将它看作是由N×M个小正方形组成。(见图) Bob的房子的形状也是矩形的,其边和土地的边是平行的,而且其顶点与某个小正方形的顶点重合。为了使房子保持平衡,Bob要选具有相同高度的小方格建造房子。

(土地被分成多个小方格。房屋的两个可能建造的位置如右图有红色和蓝色。)

请计算Bob建造房子的方案数。



Input

第 1 行输入包含N和M;

接下来的N行,每行包含M个整数A[i][j],表示该方格的土地高度。

Output

输出共一行一个整数,即任务中所需的答案。

Sample Input

【输入样例1】

5 3

2 2 2

2 2 1

1 1 1

2 1 2

1 2 1

【输入样例2】

4 3

1 1 1

1 1 1

2 2 2

2 2 2

Sample Output

【输出样例1】

27

【输出样例2】

36

Data Constraint

对于10%的数据: 1≤N,M≤50;1≤A[i][j]≤10;

对于30%的数据: 1≤N,M≤500;1≤A[i][j]≤10,000;

对于100%的数据:1≤N,M≤1,000;1≤A[i][j]≤1,000,000,000;

题解

听说正解是什么单调栈,只是吓人的,其实很简单。

对于每一位,维护up[i,j]表示这一列从上开始,有几个连续的与本位相同的数(持续至本位,包括本身,即初值为1)。那么对于一行的up[i]来说,我们再开一个栈来维护从前到目前连续的区间内,相应的矩形个数,举个例子:



额,有点丑,将就着看。

那么假设这些都是同一颜色的,我们做到3、5、9、12、16这一行,1、6号方块是没用的,那么我们可以直接删去,即最终处理出来的栈为2,2,3,3,4。

接着我们要压栈,大概就是将它压成

原数 个数

2 2

3 2

4 1

记得当颜色不一样时整个栈清零。

每次做一位统计一位。

var
n,m,i,j,k,tot:longint;
ans,jl:int64;
up,a:array[0..1000,0..1000]of longint;
z:array[0..1000,1..2]of longint;
begin
readln(n,m);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(a[i,j]);
up[i,j]:=1;
if a[i,j]=a[i-1,j] then
inc(up[i,j],up[i-1,j]);
if j=1 then
begin
fillchar(z,sizeof(z),0);
tot:=1;
z[tot,1]:=up[i,j];
z[tot,2]:=1;
inc(ans,up[i,j]);
continue;
end;
if a[i,j]<>a[i,j-1] then
begin
fillchar(z,sizeof(z),0);
tot:=1;
z[tot,1]:=up[i,j];
z[tot,2]:=1;
inc(ans,up[i,j]);
continue;
end;
if up[i,j]<z[tot,1] then
begin
jl:=1;
for k:=tot downto 1 do
begin
if up[i,j]>=z[k,1] then
break;
inc(jl,z[k,2]);
end;
if up[i,j]<z[1,1] then
begin
tot:=1;
z[tot,1]:=up[i,j];
z[tot,2]:=jl;
end
else
begin
if up[i,j]=z[k,1] then
begin
tot:=k;
inc(z[tot,2],jl);
end
else
begin
tot:=k+1;

4000
z[tot,1]:=up[i,j];
z[tot,2]:=jl;
end;
end;
for k:=1 to tot do
inc(ans,z[k,1]*z[k,2]);
continue;
end;
if up[i,j]=z[tot,1] then
inc(z[tot,2])
else
begin
inc(tot);
z[tot,1]:=up[i,j];
z[tot,2]:=1;
end;
for k:=1 to tot do
inc(ans,z[k,1]*z[k,2]);
end;
readln;
end;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  题解