1 条题解
-
0
📝 题目大意
给定一个 的方格,每个格子填有 到 的整数。判断是否构成一个合法的数独(Sudoku),即每行、每列、每个 宫格内都恰好包含 到 各一次。
💡 解题思路
-
题目分析:方格大小固定为 ,每个格子数值范围为 。需要同时验证三个条件——行、列和 宫格的无重复性。由于输入规模极小( 个格子),直接模拟检查即可,无需任何优化。
-
算法推导:
- 使用
bool ok = true作为全局合法性标志,一旦某处发现重复立即置为false并提前退出。 - 行检查:遍历每一行
i(0到8),用长度为 的布尔数组seen标记该行已出现的数字。若seen[val]已为true,说明该行出现了重复数字,ok = false并跳出。 - 列检查:仅当行检查通过(
ok == true)时继续。遍历每一列j,同样用seen数组检查该列有无重复。 - 宫格检查:仅当前两步均通过时继续。将 个 宫格编号为
block = 0..8,通过startRow = (block / 3) * 3和startCol = (block % 3) * 3计算每个宫格的左上角坐标,然后遍历宫格内的 个格子,同样用seen数组去重。 - 最终根据
ok输出"Yes"或"No"。
- 使用
-
边界与细节:
- 题目保证 ,因此
seen数组大小设为 (下标 到 有效)不会越界。 - 每个检查阶段都要在发现重复后立即
break,避免后续无意义的遍历(同时也防止seen数组被重新初始化后覆盖了错误状态)。 - 宫格检查中
block / 3和block % 3分别对应行号和列号,乘以 得到起始坐标,这是数独宫格遍历的常见技巧。
- 题目保证 ,因此
⏱️ 复杂度分析
- 时间复杂度:,每个格子被检查常数次(行、列、宫格各一次)。
- 空间复杂度:,仅需一个长度为 的布尔数组及 的输入矩阵。
💻 标准代码 (C++)
#include <iostream> #include <vector> using namespace std; int main() { // 读入 9x9 方格 vector<vector<int>> A(9, vector<int>(9)); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { cin >> A[i][j]; } } bool ok = true; // 全局合法性标志 // 1. 检查每一行是否有重复数字 for (int i = 0; i < 9; i++) { vector<bool> seen(10, false); // seen[x] 表示数字 x 是否在该行出现过 for (int j = 0; j < 9; j++) { int val = A[i][j]; if (seen[val]) { // 重复出现,不合法 ok = false; break; } seen[val] = true; } if (!ok) break; // 提前退出 } // 2. 检查每一列是否有重复数字(仅当行检查通过时进行) if (ok) { for (int j = 0; j < 9; j++) { vector<bool> seen(10, false); // seen[x] 表示数字 x 是否在该列出现过 for (int i = 0; i < 9; i++) { int val = A[i][j]; if (seen[val]) { // 重复出现,不合法 ok = false; break; } seen[val] = true; } if (!ok) break; // 提前退出 } } // 3. 检查每个 3x3 宫格是否有重复数字(仅当前两步均通过时进行) if (ok) { for (int block = 0; block < 9; block++) { // 计算当前宫格的左上角坐标 int startRow = (block / 3) * 3; int startCol = (block % 3) * 3; vector<bool> seen(10, false); // seen[x] 表示数字 x 是否在该宫格出现过 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { int val = A[startRow + i][startCol + j]; if (seen[val]) { // 重复出现,不合法 ok = false; break; } seen[val] = true; } if (!ok) break; // 提前退出内层循环 } if (!ok) break; // 提前退出外层循环 } } // 输出结果 cout << (ok ? "Yes" : "No") << endl; return 0; } -
- 1
信息
- ID
- 750
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者