您的位置:首页 > 其它

> 2242. 【2017.11.25普及组模拟】Bob

2017-11-30 14:51 281 查看
【2017.11.25普及组模拟】Bob

(File IO): input:bob.in output:bob.out

时间限制: 1000 ms 空间限制: 262144 KB 具体限制

题目描述

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

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

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

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

输入

第 1 行输入包含N和M;

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

输出

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

样例输入

【输入样例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

样例输出

【输出样例1】

27

【输出样例2】

36

数据范围限制

对于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;

比赛0分。

10分水法:四重循环,四重循环,50^4,能过。

那么,给n,m<=500(n^3)和n,m<=1000(n^2)有什么用?

设f[i,j]为以i,j为右下角所有答案矩阵的数量。

答案为所有f[i,j]相加。时间复杂度:O(n^2)

那么怎么求呢?

设up[i,j]为i,j上连续有几个,O(n^2)

画一幅图:

f[i,j]等于栈里面所有数之和

更新i时栈清空

至此完结。

代码(请勿抄袭)

pascal代码:

var
i,j:longint;
k,m,n,o,p,l,s,t,r,ans:int64;
a,up,f:array[0..1000,0..1000] of int64;
zhan:array[0..10000000] of int64;
begin
assign(input,'bob.in');reset(input);
assign(output,'bob.out');rewrite(output);
readln(n,m);
for i:=1 to n do begin
for j:=1 to m do
read(a[i,j]);
readln;
end;
for i:=1 to n do begin
for j:=1 to m do begin
if a[i-1,j]=a[i,j] then up[i,j]:=up[i-1,j]+1 else up[i,j]:=1;
end;
end;
for i:=1 to n do begin
zhan[0]:=0;
ans:=0;
for j:=1 to m do begin
if (j=1) or (a[i,j]=a[i,j-1]) then begin
inc(zhan[0]);
zhan[zhan[0]]:=up[i,j]; inc(ans,up[i,j]);
k:=zhan[0];
while (zhan[k]<zhan[k-1]) do begin
dec(ans,zhan[k-1]-zhan[k]);
zhan[k-1]:=zhan[k];
dec(k);
if k=1 then break;
end;
end else begin
zhan[0]:=1;
zhan[1]:=up[i,j];
ans:=up[i,j];
end;
f[i,j]:=ans;
end;
end;
for i:=1 to n do
for j:=1 to m do
inc(s,f[i,j]);
writeln(s);
close(input);close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: