二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放 一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。 对于两个格子坐标(x1,y1),(x2,y2)

探讨在一个W*H网格中,如何放置蛋糕使得任意两块蛋糕的欧几里得距离不等于2,以达到最大数量。通过算法设计,解决实际问题并提供代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

题目:二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根小易想知道最多可以放多少块蛋糕在网格盒子里。

输入描述:
每组数组包含网格长宽W,H,用空格分割.(1 ≤ W、H ≤ 1000)
输出描述:
输出一个最多可以放的蛋糕数
示例1:
输入
3 2
输出
4

int max_cake()
{
	int w;//长(列)
	int h;//宽(行)
	cin >> w >> h;
	int count = 0;

	vector<vector<int>> vv;
	vv.resize(h);//vv有h行

	for (auto& e : vv)
	{
		e.resize(w,1);//每个小vector有w列,即h*w的二维数组(初始化为1)
	}

	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			if (vv[i][j] == 1)
			{
				count++;

				//与这一行距离是2的行不能有(列不变)
				if (i + 2 < h)
				{
					vv[i+2][j] = 0;
				}

				//与这一列距离是2的列不能有(行不变)
				if (j + 2 < w)
				{
					vv[i][j + 2] = 0;
				}
			}
		}
	}
	return count;
}

 

1.求解涂棋盘问题。 小易有一块n*n的棋盘,棋盘的每一个格子都为黑色或者白色,小易现在要用他喜欢的红色去涂棋盘.小易会找出棋盘的某一中,拥有相同颜色的最大区城去涂画,帮助小易算算他会图多少个棋格。 输入描述:输入数据包括1+1行,第一行为一个整数n(1<=n<=50),即棋盘的大小;接下来的n行每行 一个字符串表示第{行棋盘的颇色,'W'表示白色,'B'表示照色. 输出描述:输出小易会涂画的区域大小 输入样例: 3 BWW BBB BWB 样例输出: 3 #include <iostream> #include <vector> #include <algorithm> using namespace std; // 定义方向数组,用于在棋盘上移动 int dx[] = {-1, 1, 0, 0}; int dy[] = {0, 0, -1, 1}; // 深度优先搜索函数,用于标记连通区域 void dfs(vector<vector<char>>& board, int x, int y, char color, vector<vector<bool>>& visited) { int n = board.size(); int m = board[0].size(); visited[x][y] = true; for (int i = 0; i < 4; ++i) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && nx < n && ny >= 0 && ny < m && !visited[nx][ny] && board[nx][ny] == color) { dfs(board, nx, ny, color, visited); } } } int main() { int n; cin >> n; vector<vector<char>> board(n, vector<char>(n)); vector<vector<bool>> visited(n, vector<bool>(n, false)); int maxArea = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cin >> board[i][j]; } } // 遍历棋盘,对每个未访问的格子进行DFS for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (!visited[i][j]) { int area = 0; dfs(board, i, j, board[i][j], visited); for (int x = 0; x < n; ++x) { for (int y = 0; y < n; ++y) { if (visited[x][y]) { area++; visited[x][y] = false; // 重置visited数组 } } } maxArea = max(maxArea, area); } } } cout << maxArea << endl; return 0; } 实验代码能够完成吗?
最新发布
04-01
这段代码的目标是解决“涂棋盘”问题,即寻找棋盘中由相同颜色组成的最大连续区域并返回其大小。然而,当前代码存在一些逻辑错误和改进空,导致它无法正确完成任务。 以下是详细的分析及改进建议: --- ### 1. **代码的主要功能** - 使用深度优先搜索(DFS)算法遍历棋盘的所有格子- 对于每个未访问过的格子,找到与其相连的、具有相同颜色的最大区域,并记录面积。 - 输出所有最大区域中的最大值。 --- ### 2. **存在的问题** #### (1**`visited`数组重置的问题** - 在每次调用 `dfs` 后,代码尝试通过双重循环重新统计 `area` 并清空 `visited` 数组。 - 然而这种做法非常低效且容易出错,因为 `visited` 应当在单次 DFS 内部动态更新,而不是事后手动计算区域大小后再恢复状态。 #### (2**计数逻辑不够清晰** - 区域面积应该在 DFS 的过程中实时累加,而不是依赖外部循环去逐一检查 `visited` 数组的状态。 - 这种设计不仅复杂化了代码结构,还可能导致重复计数或遗漏的情况发生。 #### (3)**优化不足** - 如果采用更高效的方式存储和传递信息,比如直接在递归函数内部维护一个局部变量保存当前区域的大小,则可以显著提升性能。 - 此外,不需要显式地定义四个方向向量 `{dx[], dy[]}` ,可以直接基于维索引操作实现邻接点判断。 --- ### 3. **修正后的完整代码** 下面是对原始代码进行了修复和完善的新版本: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; // 定义方向数组,用于在棋盘上移动 const int dx[4] = {-1, 1, 0, 0}; // 上下左右偏移量 const int dy[4] = {0, 0, -1, 1}; // 深度优先搜索函数,用于标记连通区域 int dfs(const vector<vector<char>>& board, int x, int y, char color, vector<vector<bool>>& visited) { int n = board.size(); // 获取棋盘行尺寸 if (x < 0 || x >= n || y < 0 || y >= n || visited[x][y] || board[x][y] != color) return 0; // 边界条件检测 visited[x][y] = true; // 标记当前位置已访问过 int area = 1; // 初始化当前节点贡献的一个单元格 // 探索上下左右相邻位置 for (int i = 0; i < 4; ++i) { int nx = x + dx[i]; // 新坐标 int ny = y + dy[i]; area += dfs(board, nx, ny, color, visited); // 继续探索邻居结点 } return area; // 返回包含本节点在内的总区域大小 } int main() { int n; cin >> n; vector<vector<char>> board(n, vector<char>(n)); // 存储棋盘点阵的数据结构 vector<vector<bool>> visited(n, vector<bool>(n, false));// 是否已经访问标志矩阵 // 输入棋盘数据 string line; for (int i = 0; i < n; ++i) { cin >> line; for (int j = 0; j < n; ++j) { board[i][j] = line[j]; } } int maxArea = 0; // 全局最大区域初始化为零 // 遍历整个棋盘 for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (!visited[i][j]) { // 只有没访问过得才进入DFS流程 int current_area = dfs(board, i, j, board[i][j], visited); maxArea = max(maxArea, current_area); } } } cout << maxArea << endl; // 打印最终结果 return 0; } ``` --- ### 4. **修改要点说明** - 将区域面积计算集成到 DFS 函数内,避免额外的全局变量或后续扫描步骤。 - 引入边界条件剪枝机制防止越界访问非法内存地址。 - 提高可读性和模块化程度以便后期维护升级更容易些。 --- ### §: 1. 如何利用广度优先搜索(BFS)代替上述深搜方案解决同样的题目呢? 2. 若要扩展支持更多种类的颜色字符而不局限于 'B' 和 'W', 应该做怎样的改动? 3. 假设输入规模扩大至千级甚至万级以上的大规模稀疏网格表象形式时,我们还能沿用现有的O(N^2)复杂度策略么?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值