当前位置:网站首页>21天学习挑战赛--图像物体的边界
21天学习挑战赛--图像物体的边界
2022-08-10 05:36:00 【yeah_you_are】
活动地址:CSDN21天学习挑战赛
题目描述
给一个二维数组M行N列,数组中的数字代表图片的像素,为了简化问题,仅包含像素1和5两种像素,每种像素代表一个物体,将两个不同物体相邻的格子称为边界,求像素1代表的边界个数。(0<M<100,0<<100)
其中像素1代表的物体边界是指像素为1并且与像素5相邻的格子,而相邻的概念是指八个方向(上、下、左、右、左上、左下、右上、右下)的相近。
如上图,其中黄色部分即为边界,根据相邻的概念,黄色的格子组成了两个边界。
上图中的黄色格子据相邻的概念只有一个边界。
输入示例
6 6
1 1 1 1 1 1
1 5 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 5
输出
2
解析见上图
思考
解决这个问题可以分为两步:
确定边界格子
判断边界格子所属边界的个数
那么就有了解决问题的思路,第一步确定边界格子,可以将5周围的格子标记出来,这里是数组,那就赋一个不是1、5的值就好了,这里用2标记,于是我们有了:
2 2 2 1 1 1
2 5 2 1 1 1
2 2 2 1 1 1
1 1 1 1 1 1
1 1 1 1 2 2
1 1 1 1 2 5
这样所有的边界格子被标记出来了,然后第二步判断边界格子所属边界,那么就是找2的格子,找到一个2的格子a便立即根据相邻规律将所有与格子a相邻的所有为2的格子变为3,那么找到2的次数便是边界的个数。
3 3 3 1 1 1
3 5 3 1 1 1
3 3 3 1 1 1
1 1 1 1 1 1
1 1 1 1 3 3
1 1 1 1 3 5
代码
根据上面的思考,里面都有一个给相邻格子赋值的操作,先抽象成方法。
/**给相邻的格子赋值,pixel为当前值,target为目标值,只有当前值为pixel才会有赋值操作 *i,j分别对应数组中中心点的位置 *recursion确定是否为递归 */
public void put(int i, int j, int[][] array, int pixel, int target, boolean recursion) {
//遍历上、中、下
for (int a=-1;a<=1;a++){
//遍历左、中、右
for (int b=-1;b<=1;b++) {
//确保数组下标不越界,并且数组当前位置的值为指定像素值pixel
if (i+a < array.length && i+a >= 0 &&
j+b < array[0].length && j+b >= 0 &&
array[i+a][j+b] == pixel) {
array[i+a][j+b] = target;
//递归
if (recursion) {
put(i+a,j+b, array, pixel, target, true);
}
}
}
}
}
此处定义的方法 put() 主要功能是将数组当前位置的所有相邻部分并且其像素pixel为指定值的格子赋上目标值target,当递归recursion为true时,会将根据相邻规则画出的一个块都赋上目标值。
第二步,判断边界个数,用上面的方法递归计算边界的个数。
public static void main(String[] args) {
//初始化数组
int[][] a = new int[6][6];
for (int i=0;i<a.length;i++) {
for (int j=0;j<a[0].length;j++){
a[i][j] = 1;
}
}
a[1][1] = 5;
a[5][5] = 5;
//标记像素5的边界,用2标记
for (int i=0;i<a.length;i++) {
for (int j=0;j<a[0].length;j++){
if (a[i][j] == 5)
//调用put方法标记边界
put(i,j,a,1,2,false);
}
}
//统计边界个数
int count = 0;
for (int i=0;i<a.length;i++) {
for (int j=0;j<a[0].length;j++){
//找到2的格子,并递归标记
if (a[i][j] == 2) {
put(i, j, a, 2, 3, true);
count ++;
}
}
}
System.out.println("边界个数:" + count);
}
其实这里还可以尝试用不同的值标记不同的边界,那么也许更明显,但是在尝试过程中,一定要避免2、1之类的已经出现的值,可能让递归陷入死循环,会报栈溢出错误。
至此,问题解决。
边栏推荐
猜你喜欢
随机推荐
通过adb devices命令在控制台显示企业级PicoNeo3设备号
【烘焙】肉松蛋糕卷
LeetCode 1720. Decoding XORed Arrays (Simple)
Explain the principle of MySql index in detail
51单片机BH1750智能补光灯台灯光强光照恒流源LED控制系统
ASP.Net利用代码点击相应按钮来关闭当前的页面(亲测有效)
LeetCode 1351.统计有序矩阵中的负数(简单)
LeetCode 100.相同的树(简单)
在Unity中判断游戏物体是否在游戏屏幕范围之内
以STM32F103C6TA为例通过配置CubeMX实现GPIO输出完成点灯实例
工业废酸回收工艺
Linux的文件IO与标准IO,以及IO缓存
pytorch-08. Load dataset
在Unity中让物体围绕自身的x、y、z轴进行旋转(亲测有效)
pytorch-10.卷积神经网络
LaTeX总结----在CSDN上写出数学公式
Pytorch - 07. Multidimensional characteristics of input processing
每日刷题(day03)——leetcode 899. 有序队列
VTK 初步 (1) ----- 可视化管线
Deep learning TensorFlow entry environment configuration









