中兴捧月蓝剑之路初赛题目——数房子:为了规划城市,需要统计房屋数目信息。方法如下,一张航拍照片会被分隔为M*N个小格子,用数字0或1分别表示某格子看到的是空地还是屋顶,相邻的屋顶属于同一栋房子,位于对角线上的屋顶不属于同一栋房子(这也符合实际),现在先输入航拍照片的大小(M行N列),再输入矩形俯视图的布局,要求我们输出这块矩形空地中有多少栋房子
测试用例:
TestCase 1:
Input:
5 5
0 0 0 0 0
0 1 0 1 0
0 1 0 1 0
0 1 1 1 0
0 0 0 0 0
Expected Return Value:
1
TestCase 2:
Input:
5 6
1 1 0 0 1 0
0 1 1 1 0 0
1 0 0 1 0 0
0 0 0 0 1 1
0 0 0 0 1 1
Expected Return Value:
4
这道题目其实很简单,只要用一个set来存放数值是1的点就可以了我的思路就是,用一个来set(pair(int,int))存放数据,然后每次找相邻的要是有就删掉与这个点相邻的并且延伸出去也符合相邻条件的为1的点,然后每删一次count+1,判断set是否为空,不为空就再删一次.
贴代码:
#include<iostream>
#include<set>
using namespace std;
bool search(set<pair<int, int>> temp, int num_1, int num_2);
void eras(set<pair<int, int>> &temp, int num_1, int num_2, int m, int n);
int main() {
int m, n;
while(cin >> m >> n) {
int count = 0;
set<pair<int, int>> temp;
int **arr = new int*[m];
for (int i = 0; i < m; i++)
arr[i] = new int[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> arr[i][j];
if (arr[i][j] == 1)
temp.insert(pair<int, int>(i, j));
}
}
//这是房屋计数的代码
while (!temp.empty()) {
eras(temp, temp.begin()->first, temp.begin()->second, m, n);
count++;
}
for (int i = 0; i < m; i++)
delete[] arr[i];
delete[] arr;
cout <<"房屋数量为"<< count << endl;
}
return 0;
}
bool search(set<pair<int, int>> temp, int num_1, int num_2) {
//这个是判断与它相邻的点是否在set中
if (!temp.empty()&&temp.find(pair<int, int>(num_1, num_2)) != temp.end())
return true;
return false;
}
void eras(set<pair<int, int>> &temp, int num_1, int num_2, int m, int n) {
//递归删除相邻的,不过我懒,非递归的写法就不写了.
if (temp.empty())
return;
temp.erase(pair<int, int>(num_1, num_2));
if (num_2>0 && search(temp, num_1, num_2 - 1))
eras(temp, num_1, num_2 - 1, m, n);
if (num_2<n - 1 && search(temp, num_1, num_2 + 1))
eras(temp, num_1, num_2 + 1, m, n);
if (num_1>0 && search(temp, num_1 - 1, num_2))
eras(temp, num_1 - 1, num_2, m, n);
if (num_1<m - 1 && search(temp, num_1 + 1, num_2))
eras(temp, num_1 + 1, num_2, m, n);
}