问题描述:
有一个M*N的二维球场看台,已知同一个球迷群体的球迷会选择相邻座位,不同球迷群体的球迷选择不相邻的座位。给定座位选择矩阵(0表示未选择,1表示已选择),要求找出球迷群体的个数以及最大的球迷群体的人数。
(相邻包括前后、左右、斜对角相邻)
问题分析:
对于每一个座位,采用递归方法查看其8个相邻位置。对于已经访问过的位置,注意做标记。
代码实现:
#include <iostream>
#include <vector>
using namespace std;
int check(int i, int j);
int M, N; // M行N列
vector<vector<int>> seats; // 没球迷:0,有球迷:1,若被访问过,则置为-1
void main()
{
cin >> M;
cin.get();
cin >> N;
// 读取矩阵
seats.reserve(M);
for (int i = 0; i < M; i++)
{
vector<int> row(N);
for (int j = 0; j < N; j++)
{
cin >> row[j];
cin.get();
}
seats.push_back(row);
}
// 聚合
int groupSize;
int maxSize = 0;
int groupNum = 0;
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
groupSize = check(i , j);
if (groupSize > 0)
groupNum++;
if (groupSize > maxSize)
maxSize = groupSize;
}
}
// 输出
cout << groupNum << "," << maxSize << endl;
cin.get();
}
// 以i, j为中心递归搜索
int check(int i, int j)
{
// 越界或已被访问
if (i < 0 || j < 0 || i > M - 1 || j > N - 1 || seats[i][j] <= 0)
return 0;
// 标记为已访问
seats[i][j] = -1;
int groupSize = 1;
// 查找上、下、左、右、斜对角的位置
groupSize += check(i - 1, j) + check(i + 1, j) + check(i, j - 1) + check(i, j + 1)
+ check(i - 1, j - 1) + check(i + 1, j + 1) + check(i + 1, j - 1) + check(i - 1, j + 1);
return groupSize;
}