题意:
他迫切需要机器帮他判断,哪种细菌的地盘更大。
你能帮帮他吗?
注意如果两块细菌不连通,即使他们是同一种细菌,也要分开计算,例如:
5 5
0 0 0 0 0
0 1 1 0 0
0 2 2 2 0
0 0 0 0 0
0 0 1 1 0
虽然这里的1
占据了4个格子,但他分为两块,每块各占2个格子,而2
号细菌只有一个块,占据3个格子。因此2
号胜出,你应该输出:
2 3
思路:
①用STL中的vector记录细菌的分布,每个细菌存为一个结构体,包括坐标、细菌标号、遍历标志。
②用STL中的stack(栈)来替代递归的做法。
③遍历菌落。若改菌落未被遍历,则压入栈。进入栈循环(循环条件为栈非空),遍历出栈细菌,若该点未遍历,则细菌数+1且更新为已遍历状态。出栈循环后更新最大菌落及其次数。
源码:
#include <iostream>
#include<stack>
#include<vector>
using namespace std;
struct poi //定义细菌结构体
{
int x{ 0 }, y{ 0 };
int flag{ 0 };
int num{ 0 };
};
int main() {
int w = 0, h = 0, maxnum = 0, maxtime = 0, cnt = 0;
stack<poi>s;
cin >> w >> h;
vector<vector<poi>> map(h); //菌落分布
for (int i = 0; i < h; i++) //初始化菌落分布
map[i].resize(w);
for (int i = 0; i < h; i++) { //更新菌落状态地图
for (int j = 0; j < w; j++) {
cin >> map[i][j].num;
map[i][j].x = j;
map[i][j].y = i;
}
}
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (map[y][x].num == 0||map[y][x].flag==1) //坐标点有细菌且已遍历则跳过
continue;
map[y][x].flag = 1; //更新遍历状态
s.push(map[y][x]); //该点入栈
cnt = 0; //初始化细菌出现次数
while (!s.empty()) {
cnt++;
poi n = s.top(); //出栈一个细菌
s.pop();
if (n.x - 1 > -1 && map[n.y][n.x - 1].num == map[n.y][n.x].num&& map[n.y][n.x - 1].flag != 1) { //遍历周围细菌
s.push(map[n.y][n.x - 1]);
map[n.y][n.x - 1].flag = 1;
}if (n.x + 1 < w && map[n.y][n.x + 1].num == map[n.y][n.x].num&& map[n.y][n.x + 1].flag != 1) {
s.push(map[n.y][n.x + 1]);
map[n.y][n.x + 1].flag = 1;
}if (n.y - 1 > -1 && map[n.y - 1][n.x].num == map[n.y][n.x].num && map[n.y - 1][n.x].flag != 1) {
s.push(map[n.y - 1][n.x]);
map[n.y - 1][n.x].flag = 1;
}if (n.y + 1 < h && map[n.y + 1][n.x].num == map[n.y][n.x].num && map[n.y + 1][n.x].flag != 1) {
s.push(map[n.y + 1][n.x]);
map[n.y + 1][n.x].flag = 1;
}
}
if (cnt > maxtime) { //更新最大菌落状态
maxtime = cnt;
maxnum = map[y][x].num;
}
}
}
if (maxtime == 0) //输出
cout << "None" << endl;
else
cout << maxnum << " " << maxtime << endl;
return 0;
}
ps:栈循环中的遍历细菌条件要写好。