水题

题意:给你一个0,1矩阵,数字1相当于是围墙,有一些数字0会被数字1完全围住,现在要求你把被围住的数字输出时全部输出2,其余数字输出时原样输出。

思路:被所有的1围住肯定就不和边界接壤了呗,我们就从与边界接壤的0开始搜索,然后求联通快,块里的所有数字0全部标记为1,原先的数字1也标记为1.最后被标记的原样输出,没被标记的输出2就可以了。结果这道题给敲错了,bfs又无限入队了。因为我判断是否入队的条件是,只要下一个 数字不越界并且不是1就入队,但是这样就导致了某个子节点的父节点会重复入队,因为它永远为0且永远不越界。所以正确的判断方法应该是 ,不越界,并且没有被访问过,且不为1.这样就避免了重复入队。

#include<bits/stdc++.h>
using namespace std;

int n;
int w[40][40];
int visit[40][40];
struct node
{
    int dx,dy;
}dir[5];

struct node2{
  int x,y;
};

queue<node2> q;

void bfs(int x,int y)
{
    struct node2 a;
    a.x=x;a.y=y;
    q.push(a);
    while(!q.empty())
    {
       node2 b;
       b=q.front();
       q.pop();
       for(int i=1;i<=4;i++)
       {
           int xx,yy;
           xx=b.x+dir[i].dx;
           yy=b.y+dir[i].dy;
           if(xx>=1&&yy>=1&&xx<=n&&yy<=n)
           {
               if(!visit[xx][yy])
               {
                   visit[xx][yy]=1;
                   node2 c;
                   c.x=xx;c.y=yy;
                   q.push(c);
               }
           }
       }
    }
    return ;
}


int main()
{
    dir[1].dx=0;dir[1].dy=-1;
    dir[2].dx=-1;dir[2].dy=0;
    dir[3].dx=0;dir[3].dy=1;
    dir[4].dx=1;dir[4].dy=0;

   cin>>n;
   for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
    cin>>w[i][j];
    if(w[i][j]==1)
        visit[i][j]=1;
    }


    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
    {
        if(i==1||i==n||j==1||j==n)
        {
            if(!visit[i][j])
            {
                visit[i][j]=1;
                bfs(i,j);
                //cout<<"111111111111
";
            }
        }

    }

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
        if(visit[i][j])
        cout<<w[i][j]<<" ";
        else
            cout<<"2"<<" ";
        }
        cout<<"
";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/rainyskywx/p/11056187.html