牛客网商汤研究员--[编程题]分割后处理

 

链接:https://www.nowcoder.com/questionTerminal/4ce64fe976c548f5beacfe47faf666b0?answerType=1&f=discussion

研究地球空间科学的永强想研究海岸线的长度和海岸线面积之间的关系,为此他找来了很多航拍图像。在航拍图像上利用图像分割的方法,把图像的每个像素标记成陆地(1)和水面(0)。

示例图片:

 

现在永强想知道每张图中陆地部分的面积。

 

已知每张图最底部的一条边都是陆地,并且在一张图上陆地都是四邻域联通的。

但是永强发现分割的结果有很多的噪声,于是他定义了如下规则试图去除噪声:

a)    如果一个水面区域被陆地包围,则将这个区域记为陆地;
b)    在a的基础上如果一个陆地区域不和底边的陆地相连,那么这是一个岛屿,不计入陆地的面积。

 

输入描述:

第一行为两个整数m和n,
接下来m行每行会有n个数,0表示水面,1表示陆地。

 

输出描述:

去噪后陆地部分的面积。

示例1

输入

5 6
1 0 0 1 0 0
0 0 1 0 1 0
1 1 1 1 1 0
1 0 0 1 1 1
1 1 1 1 1 1

输出

21

思路:

针对四连通规则,对陆地和海洋进行划分。

代码

//为了方便查看数组的变化,可以将注释取消。
#include <iostream>
#include <queue>
using namespace std;
int m, n;
int sum = 0;
//4连通区域重新打标签,key为原标签值,i为行,j为列,set是新的标签值
void link(vector<vector<int>>&nums,int key, int i, int j,int set)
{
	sum++;
	nums[i][j] = set;
/*	for (int s = 0; s < m; s++)
	{
		for (int h = 0; h < n; h++)
			cout << nums[s][h]<<' ';
		cout << endl;
	}
	cout << endl;
	*/
//对每一个符合标签值的点的4邻域的数据点做判断,完成一个连通区域
	if (i - 1 >= 0 && nums[i - 1][j] == key) link(nums,key, i - 1, j, set);
	if (i + 1 < m && nums[i + 1][j] == key) link(nums, key, i + 1, j, set);
	if (j - 1 >= 0 && nums[i][j - 1] == key) link(nums,key, i, j - 1, set);
	if (j + 1 < n && nums[i][j + 1] == key) link(nums, key, i, j + 1, set);
}
int main()
{
	cin >> m>>n;
	vector<vector<int>>temp(m, vector<int>(n));
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
		{
			cin >> temp[i][j];
		}
	}
	for (int i = 0; i < n; i++)//对第一行的海进行连通
	{
		if (temp[0][i] == 0) link(temp,0, 0, i, -1);
	}
	/*
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
			cout << temp[i][j]<<" ";
		cout << endl;
	}
	*/
	for (int i = 0; i < m; i++)//对第一列和最后一列的海做连通
	{
		if (temp[i][0] == 0) link(temp, 0, i, 0, -1);
		if (temp[i][n - 1] == 0) link(temp,0, i, n - 1, -1);
	}
	/*
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
			cout << temp[i][j];
		cout << endl;
	}
	*/
	for (int i = 0; i < m;i++)
	for (int j = 0; j < n;j++)
	if (temp[i][j] == 0) temp[i][j] = 1;
	/*
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
			cout << temp[i][j];
		cout << endl;
	}
	*/
	sum = 0;
	link(temp,1, m-1, 0, 2);//以左下角的点为起始点做连通,得到整个陆地的面积
/*	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
			cout << temp[i][j];
		cout << endl;
	}
	*/
	cout << sum;
	return 0;
}

分析

代码逻辑没有问题,但是超内存了,只AC了91.67%

关于优化,暂时没想法。有想法的朋友欢迎留言!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值