DS–图非0面积

  • Post author:
  • Post category:其他




DS–图非0面积



题目描述

编程计算由”1″围成的下列图形的面积。面积计算方法是统计”1″所围成的闭合曲线中”0″点的数目。如图所示,在10*10的二维数组中,”1″围住了15个点,因此面积为15。

在这里插入图片描述



输入

测试次数t

每组测试数据格式为:

数组大小m,n

一个由0和1组成的m*n的二维数组



输出

对每个二维数组,输出符号”1″围住的”0″的个数,即围成的面积。假设一定有1组成的闭合曲线,但不唯一。



样例输入

2

10 10

0 0 0 0 0 0 0 0 0 0

0 0 0 0 1 1 1 0 0 0

0 0 0 0 1 0 0 1 0 0

0 0 0 0 0 1 0 0 1 0

0 0 1 0 0 0 1 0 1 0

0 1 0 1 0 1 0 0 1 0

0 1 0 0 1 1 0 1 1 0

0 0 1 0 0 0 0 1 0 0

0 0 0 1 1 1 1 1 0 0

0 0 0 0 0 0 0 0 0 0

5 8

0 1 1 0 0 1 1 0

1 0 1 0 1 0 0 1

0 1 0 1 0 0 1 0

0 1 0 0 1 1 1 0

0 0 0 0 0 0 0 0



样例输出

15

5



个人理解

首先想到的是把外围的0全部变成1,然后再遍历矩阵得到0的个数,也即是面积

那么如何将外围的0变为1?

使用bfs算法,从(0,0)位置开始bfs,将上下左右认为是邻接点(这样就不会bfs到围起来的面积里面

然而wc了

出错原因:应该要从四面八方进行bfs,比如说,如果你从矩阵的左上角进行bfs,可能很快遇到了一堵墙,但是真正围成的面积在矩阵的更里面,这就导致了多余的0未变为1

解决方案

将矩阵往右下角移动,左上方向腾出一行一列,即矩阵的左上角变为(1,1),然后再从(0,0)位置进行bfs



程序

#include<iostream>
#include<queue>
using namespace std;

/*值得注意的是,为了避免出现阻挡,例如例2的(0,0)位置被两个1挡住了
所以bfs从外面环绕遍历*/
class Map
{
public:
    int graph[100][100];
    int m,n;
    void initialize()
    {
        for(int i=0;i<=m+1;i++)//先将二维数组初始化为0
            for(int j=0;j<=n+1;j++)
                graph[i][j]=0;
        cin >> m >> n;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                cin >> graph[i][j];
    }
    void BFS()
    {
        int x=0,y=0;
        queue<int> Qx,Qy;
        Qx.push(x);
        Qy.push(y);
        graph[x][y]=1;
        int nx[4]={-1,0,1,0};//在for循环中分别对应上下左右的结点
        int ny[4]={0,1,0,-1};
        while(!Qx.empty()){
            for(int i=0;i<4;i++){//判断上下左右的结点是否合格
                if(Qx.front()+nx[i]>=0&&Qx.front()+nx[i]<=m+1&&Qy.front()+ny[i]>=0&&Qy.front()+ny[i]<=n+1&&graph[Qx.front()+nx[i]][Qy.front()+ny[i]]==0){
                    Qx.push(Qx.front()+nx[i]);
                    Qy.push(Qy.front()+ny[i]);
                    graph[Qx.front()+nx[i]][Qy.front()+ny[i]]=1;//合格就变成墙
                }
            }
            Qx.pop();
            Qy.pop();
        }

    }
    void print()
    {
        int num=0;
        for(int i=0;i<=m;i++)
            for(int j=0;j<=n;j++)
                if(graph[i][j]==0)num++;
        cout<<num<<endl;
    }
    void print1()//打印数组
    {
        for(int i=0;i<=m+1;i++){
            for(int j=0;j<=n+1;j++)
                cout << graph[i][j] << ' ';
            cout << endl;
        }
    }
};

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        Map mygraph;
        mygraph.initialize();
        mygraph.BFS();
        mygraph.print();
        mygraph.print1();
    }
    return 0;
}



运行结果

在这里插入图片描述



目的

一个笔记



版权声明:本文为NP_hard原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。