面向对象程序设计——求小岛面积(C++)

在这里插入图片描述

问题描述

用一个二维方阵(最小为3X3,最大为9X9)表示一片海域。方阵中的元素只由0和1组成。1表示海岸线。计算由海岸线围起来的小岛面积(即:由1围起来的区域中0的个数)。如下图所示6X6方阵表示的小岛面积为9:
0 0 0 1 0 0
0 0 1 0 1 0
0 1 0 0 0 1
1 0 0 0 1 0
1 0 1 0 1 0
1 1 0 1 1 1
上述方阵表示的海域满足下面两个要求:
1、小岛只有一个。
2、用1表示的海岸线肯定可以封闭成一个小岛,但有可能是凸的,也有可能是凹的。所以在判断时:对于方阵中的任意一个元素0,如果其位于同一行上的两个1之间,并且位于同一列上的两个1之间,则该元素肯定在1围起来的区域中。不符合该规定的其它情况不考虑。

【输入形式】

先从标准输入中输入方阵的阶数,然后从下一行开始输入方阵的元素(只会输入0或1),各元素之间以一个空格分隔,每行最后一个元素后没有空格,但会有回车换行符。

【输出形式】

在标准输出上输出用整数表示的小岛面积。

【输入样例】

6
0 0 0 1 0 0
0 0 1 0 1 0
0 1 0 0 0 1
1 0 0 0 1 0
1 0 1 0 1 0
1 1 0 1 1 1

【输出样例】

9

【样例说明】

输入是6X6的方阵。该方阵中由1围起来的区域内有9个0,所以输出的小岛面积为9。注意:最下方的三个元素1(即第5行第3列的1、第6行第2列的1、第6行第4列的1)组成了一个凹形的海岸线,第6行第3列的0不在海岸线内,所以不应算作小岛面积。

解题思路

其实这一题思路很简单的,题目中也已经给出了判断一个点为小岛的方法。

对于方阵中的任意一个元素0,如果其位于同一行上的两个1之间,并且位于同一列上的两个1之间,则该元素肯定在1围起来的区域中。不符合该规定的其它情况不考虑。

我们只需要遍历所有的非边界点,并判断每个点是否满足上述的条件即可。嘴上这么说,但是在实现的时候,确实出现了一些问题。

我将所有的点存入了一个二维数组中,在对每个点进行遍历的时候,想通过一个函数来实现判断。

cin>>n;
    int graph[n][n];
    int s=0;

    for(i=0;i<n;i++){
        for(j=0;j<n;j++){
            cin>>graph[i][j];
        }
    }

但是函数传入二位参数比较复杂,或者就需要共有多少列元素,不能满足设计需求,此处想到一个折中的方法,即函数的输入输出分别如下:

  • 输入:二维数组的一列或一行,待判定元素在该列或行中的位置,该列或行共有元素个数
  • 输出:若为小岛,则输出true,反之输出false

但是在如何传入二维数组的某列或某行时,出现了问题。最终无奈选择了如下的实现方式。

for(i=1;i<n-1;i++){
        for(j=1;j<n-1;j++){
            if(graph[i][j]==0&&yjudge(graph[0]+j,i,n)&&xjudge(graph[i],j,n))//当某点的元素为0且该行和列满足要求时
                s++;
        }
    }

其中graph[0]+j本意想实现传入小岛某一列的目标,但最后发现,该传参方法要想实现对某一列元素的遍历,需要按照下述方法进行遍历:

bool yjudge(int graph[],int i,int n){
    int temp;
    for(temp=0;temp<i;temp++){
        if(graph[temp*n]==1){//当访问某列的下一个元素时,需要向下取n个元素进行访问。
            for(temp=i+1;temp<n;temp++){
                if(graph[temp*n]==1){
                    return true;

                }
            }
        }
    }
    return false;
}

二维数组在计算机中是按照如下方式进行存储的
在这里插入图片描述
因此当需要访问某列的元素时,需要向下访问该行元素的个数。
对于某行元素的判断函数如下:

bool xjudge(int graph[],int i,int n){
    int temp;
    for(temp=0;temp<i;temp++){
        if(graph[temp]==1){
            for(temp=i+1;temp<n;temp++){
                if(graph[temp]==1){
                    return true;

                }
            }
        }
    }
    return false;
}

在这里也希望路过的各位有更好的方法可以留言分享~

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值