[BZOJ1102] [POI2007]山峰和山谷Grz

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1102

题目大意

给定n*n的点的高度,8连通,相同高度的点周围的点都比它高,那它就是山谷,都比它低就是山峰,询问山峰和山谷数目

题解

BFS,floodfill即可
注意所有点高度相同,即是山峰又是山谷,都为1

const
 x:array[1..8]of integer=(0,-1,-1,-1,0,1,1,1);
 y:array[1..8]of integer=(-1,-1,0,1,1,1,0,-1);
var
 ans,w:array[0..1005,0..1005]of longint;
 t:array[0..1000005,1..2]of longint;
 i,j,k:longint;
 n,ans1,ans2:longint;
 c,d,xx,yy,head,tail,len,v:longint;
procedure dfs(a,b:longint);
var i,j,k:longint;
begin
 t[1,1]:=a; t[1,2]:=b; ans[a,b]:=1; head:=1; tail:=2; len:=1; v:=w[a,b];
 j:=0; k:=0; len:=1;
 while head<tail do begin
  c:=t[head,1]; d:=t[head,2]; inc(head);
  for i:=1 to 8 do
   begin
    xx:=c+x[i]; yy:=d+y[i];
    if (xx<1)or(xx>n)or(yy<1)or(yy>n)
    then continue;
    if (w[xx,yy]=v)and(ans[xx,yy]=0)
    then begin inc(len); t[tail,1]:=xx; t[tail,2]:=yy; inc(tail); ans[xx,yy]:=1; end;
    if w[xx,yy]<v then j:=1;
    if w[xx,yy]>v then k:=1;
   end;
 end;
 for i:=1 to len do
  ans[t[i,1],t[i,2]]:=len;
 if (j=1)and(k=0) then inc(ans1);
 if (j=0)and(k=1) then inc(ans2);
end;

begin
 readln(n); ans1:=0; ans2:=0;
 for i:=1 to n do begin
  for j:=1 to n do
   read(w[i,j]);
  readln;
 end;
 fillchar(ans,sizeof(ans),0);
 for i:=1 to n do
  for j:=1 to n do
   if ans[i,j]=0
   then dfs(i,j);
 v:=w[1,1]; k:=0;
 for i:=1 to n do
  for j:=1 to n do
   if w[i,j]<>v then begin k:=1; break; end;
 if k=0 then begin ans1:=1; ans2:=1; end;
 writeln(ans1,' ',ans2);
end.

你可能感兴趣的:([BZOJ1102] [POI2007]山峰和山谷Grz)