POJ 1652 Holey Cloth (bfs)

题意:求含有孔数最多的一块区域,如果孔数相同,那么输出区域最小(也就是含'*'最少的区域)

思路:首先用bfs求每一个连续的区域,然后把相邻的可能是孔的点记录下来,然后每个孔分别bfs,bfs时要检测一个孔是否在区域内部时,只需要查询一个点的四个方向,如果有一个方向在区域的外部,那么这片孔就不是区域的内部,如果查询后在区域中,那么孔数就+1。写的时候细节比较多,这个题也可用dfs做,代码比较短,bfs的话代码就比较长了。

  
    
#include < iostream >
#include
< cstdio >
#include
< algorithm >
#include
< memory.h >
#include
< cmath >
#include
< bitset >
#include
< vector >
using namespace std;

const int BORDER = ( 1 << 26 ) - 1 ;
const int MAXSIZE = 37 ;
const int MAXN = 150 ;
const int INF = 0x6ffffff ;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) (x>0?x:-x)

#define SET_NODE(no,a,b) {no.x=a;no.y=b;}
typedef
struct {
int x,y;
}Node;
Node que[BORDER
+ 5 ],hole[MAXN * MAXN],t_node;
int direct[ 4 ][ 2 ] = {{ 1 , 0 },{ - 1 , 0 },{ 0 , 1 },{ 0 , - 1 }};
int st,en;
int n,m,n_hole,ans_wall,ans_hole,cur_wall,cur_hole;
int arr[MAXN][MAXN],v_wall[MAXN][MAXN],v_hole[MAXN][MAXN];
int visit[MAXN][MAXN];
int _is( const int & x, const int & y)
{
if (x < 0 || x >= n)
return false ;
if (y < 0 || y >= m)
return false ;
return true ;
}
int init()
{
ans_hole
= 0 ;
ans_wall
= INF;
CLR(arr,
0 );
CLR(v_wall,
0 );
CLR(v_hole,
0 );
CLR(visit,
0 );
return 0 ;
}
bool _in( const int & x, const int & y)
{
int i,j,a,b;
for (i = 0 ; i < 4 ; ++ i)
{
a
= x;
b
= y;
while ( true )
{
a
+= direct[i][ 0 ];
b
+= direct[i][ 1 ];
if ( ! _is(a,b))
return false ;
if (arr[a][b] && v_wall[a][b])
break ;
}
}
return true ;
}
int bfs_wall( const int & sx, const int & sy)
{
int i,j,a,b,x,y;
/* init */
CLR(v_wall,
0 );
CLR(v_hole,
0 );
st
= 0 ;
en
= 1 ;
cur_wall
= 0 ;
n_hole
= 0 ;
SET_NODE(que[
0 ],sx,sy);
v_wall[sx][sy]
= 1 ;
visit[sx][sy]
= 1 ;
while (st < en)
{
a
= que[st].x;
b
= que[st].y;
++ cur_wall;
ADD(st);
for ( i = 0 ; i < 4 ; ++ i)
{
x
= a + direct[i][ 0 ];
y
= b + direct[i][ 1 ];
if (_is(x,y))
{
if (arr[x][y])
{
if ( ! v_wall[x][y])
{
SET_NODE(que[en],x,y);
ADD(en);
v_wall[x][y]
= 1 ;
visit[x][y]
= 1 ;
}
}
else
{
if ( ! v_hole[x][y])
{
SET_NODE(hole[n_hole],x,y);
v_hole[x][y]
= 1 ;
++ n_hole;
}
}
}
}
}
return 0 ;
}
int bfs_hole( const int & sx, const int & sy)
{
int a,b,x,y,i,j,flag;
st
= 0 ;
en
= 1 ;
flag
= 0 ;
SET_NODE(que[
0 ],sx,sy);
while (st < en)
{
a
= que[st].x;
b
= que[st].y;
ADD(st);
if ( ! flag)
if ( ! _in(a,b))
{
flag
= - 1 ;
}
for (i = 0 ; i < 4 ; ++ i)
{
x
= a + direct[i][ 0 ];
y
= b + direct[i][ 1 ];
if (_is(x,y))
{
if (arr[x][y])
{
;
}
else
{
if ( ! v_hole[x][y])
{
SET_NODE(que[en],x,y);
ADD(en);
v_hole[x][y]
= 1 ;
}
}
}
else
{
return - 1 ;
}
}
}
return flag;
}
int work()
{
int i,j,tmp,k;
for (i = 0 ; i < n; ++ i)
for (j = 0 ; j < m; ++ j)
{
if (arr[i][j] && ! visit[i][j])
{
bfs_wall(i,j);
CLR(v_hole,
0 );
cur_hole
= 0 ;
for (k = 0 ; k < n_hole; ++ k)
{
if ( ! v_hole[hole[k].x][hole[k].y])
{
tmp
= bfs_hole(hole[k].x,hole[k].y);
if (tmp == - 1 )
continue ;
else
++ cur_hole;
}
}
if (cur_hole == ans_hole && cur_hole != 0 )
ans_wall
= MIN(ans_wall,cur_wall);
else if (cur_hole > ans_hole)
{
ans_hole
= cur_hole;
ans_wall
= cur_wall;
}
}
}
if (ans_wall < INF)
OUT(ans_wall);
else
{
ans_wall
= 0 ;
OUT(ans_wall);
}
return 0 ;
}
int input()
{
int i,j;
char str[MAXN];
for (i = 0 ; i < n; ++ i)
{
scanf(
" %s " ,str);
for (j = 0 ; j < m; ++ j)
if (str[j] == ' * ' )
arr[i][j]
= 1 ;
}
return 0 ;
}
int main()
{
while (scanf( " %d%d " , & m, & n) != EOF)
{
init();
input();
work();
}
return 0 ;
}

 

你可能感兴趣的:(poj)