您的位置:首页 > 其它

[NOIP集训]10月19日

2015-10-20 13:00 253 查看
今天的文件夹:10月19日.zip

今天中午讲了一下昨天的题,还是有水平的。

下午复习搜索,居然有NOI难度的题,不过给了讲解,也有参考程序,就不多说了。主要说说第一题。

T1:这是道BFS练手题,但都写不对。第一个难点是读入,虽然题目中给的读入顺序很吓人,但仔细想想,就类似于“字典序比较”了。在Pascal中可以直接这样读入:

for i:=1 to l do
for j:=1 to w do
for k:=1 to h do
read(a[i,j,k]);


读入之后,按照与读入相同的顺序进行查找,找到第一个未被标记的点,然后以它为起点做一次BFS(搜索中注意及时更新标记,把所有可以判断为同一区域的点标记下来)。做完这一次BFS,标记已被更新,从上次的位置开始继续查找。这样找过一遍之后,可以保证所有点都被标记,统计所有BFS起点的个数即可。

代码:

 program scan;
var
l,w,h,m:longint;
a,b:array[-1..51,-1..51,-1..51] of longint;
i,j,k:byte;
n,left,right:longint;
x0,y0,z0:byte;
queue:array[1..1000000,1..3] of byte;
procedure clear();
begin
left:=1;
right:=0;
end;
procedure enque(x,y,z:longint);
begin
inc(right);
queue[right,1]:=x;
queue[right,2]:=y;
queue[right,3]:=z;
b[x,y,z]:=n;
end;
procedure deque();
begin
inc(left);
end;
function check(t:longint):boolean;
begin
if (x0<1)or(x0>l)or(y0<1)or(y0>W)or(z0<1)or(z0>h) then
exit(false);
if b[x0,y0,z0]>0 then
exit(false);
if abs(a[x0,y0,z0]-t)<=m then
exit(true)
else
exit(false);
end;
procedure bfs(x,y,z:longint);
begin
clear();
enque(x,y,z);
while (left<=right) do
begin
x:=queue[left,1];
y:=queue[left,2];
z:=queue[left,3];
deque();
x0:=x-1; y0:=y; z0:=z;
if check(a[x,y,z]) then
enque(x0,y0,z0);
x0:=x+1; y0:=y; z0:=z;
if check(a[x,y,z]) then
enque(x0,y0,z0);
x0:=x; y0:=y-1; z0:=z;
if check(a[x,y,z]) then
enque(x0,y0,z0);
x0:=x; y0:=y+1; z0:=z;
if check(a[x,y,z]) then
enque(x0,y0,z0);
x0:=x; y0:=y; z0:=z-1;
if check(a[x,y,z]) then
enque(x0,y0,z0);
x0:=x; y0:=y; z0:=z+1;
if check(a[x,y,z]) then
enque(x0,y0,z0);
end;
end;
begin
assign(input,'scan.in');
reset(input);
assign(output,'scan.out');
rewrite(output);
readln(l,w,h,m);
for i:=1 to l do for j:=1 to w do for k:=1 to h do read(a[i,j,k]);
fillchar(b,sizeof(b),0);
n:=0;
for i:=1 to l do
for j:=1 to w do
for k:=1 to h do
if b[i,j,k]=0 then
begin
inc(n);
bfs(i,j,k);
end;
writeln(n);
close(input);
close(output);
end.


scan.pas
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: