学习目标与前置知识
- 明确搜索状态、合法选择与终止条件,完成能通过本地判题的 C++17 解答。
- 用边界输入解释本题的常见错误,说明剪枝或最短距离为何正确。
- 前置:本章相关知识,C++ 函数、容器、递归,以及题目所用的队列或位运算。
题目描述
填满9×9数独,使每行、每列、每个3×3宫都包含1到9且不重复。每个格子的得分是填入数字乘以该格权重:最外圈6分,向中心逐圈为7、8、9分,中心格10分。给定数字不能修改,也计入总分。求全部合法填法中的最高总分,无解则输出-1。
本 Lab 保留原题的标准输入/输出合同。
输入格式
9行,每行9个整数,0表示空格,1到9表示给定数字。
输出格式
输出最高总分;无法合法填满时输出 -1。
数据范围
固定9×9,给定数字为0到9,至少24个格子非零。输入可能无解,也可能存在多个解。
样例输入
text
7 0 0 9 0 0 0 0 1
1 0 0 0 0 5 9 0 0
0 0 0 2 0 0 0 8 0
0 0 5 0 2 0 0 0 3
0 0 0 0 0 0 6 4 8
4 1 3 0 0 0 0 0 0
0 0 7 0 0 2 0 9 0
2 0 1 0 6 0 8 0 4
0 8 0 5 0 4 0 1 2样例输出
text
2829状态与边界
维护行列宫约束与当前得分,用候选数最少的空格分支;忽略空格间冲突可得到乐观的剩余得分上界。
不能复用只找首解的数独代码后直接返回分数;计算上界和总分时都不能漏掉原有数字。0基坐标(r,c)的权重是6+min(r,c,8-r,8-c)。
复杂度目标
设空格数E,保守时间上界 O(81 * 9^E),最少候选和分数上界剪枝减少分支;辅助空间 O(81+E)。
编写与测试
修改 student/main.cpp 中的 solve,保留读写框架。标准输出只保留答案,调试信息写入标准错误。测试清单和分值以 tests/cases.json 为准,总分 100 分,输入均符合本页约定。
在仓库根目录执行:
powershell
pnpm lab:run -- labs/chapter-15/exercise/E-15-20-target-sudoku
pnpm lab:score -- labs/chapter-15/exercise/E-15-20-target-sudoku进入本 Lab 目录后也可以运行 make run。作者与 CI 严格核验:
powershell
pnpm lab:verify -- labs/chapter-15/exercise/E-15-20-target-sudoku完成清单
思考与复盘
- 哪些信息必须随当前路径恢复,哪些信息可以保留?
- 去掉本题的一条约束或剪枝,会影响正确性还是只影响效率?请用具体输入说明。
- 输入达到上限时,时间、递归深度和输出大小分别如何增长?
题目来源与课程化说明
来源:洛谷 P1074 靶形数独。题面按课程环境重新表述,参考实现和测试独立编写,不复制第三方题解或隐藏测试。完整参考代码位于 solution/main.cpp。