zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    GIT的使用
    C# DataTable.Select() 筛选数据
    Oracle数据库使用游标查询结果集所有数据
    清除PLSQL Developer访问数据库连接的历史记录
    C#关于DateTime得到的当前时间的格式和用法
    C++中string的用法
    ACM讲课之字符串
    第二场周赛(递归递推个人Rank赛)——题解
    ACM团队招新赛题解
    线段树详解
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1711799.html
Copyright © 2011-2022 走看看