我正在阅读“编程访谈元素”一书,我遇到了为数独检查程序编写解决方案的问题。我能够轻松地弄清楚如何检查以确保当前列和行中的任何其他位置都找不到当前元素,但事实证明,检查当前子网格中的重复项是非常重要的。
我遇到问题的问题是如何知道当前元素所在的子网格(当您遍历2D数组时)以及该子网格开始的位置。
本书中的解决方案似乎通过执行以下操作来检查每个子网格:
bool isValidSudoku(const vector<vector<int>>& partial_assignment) {
//Code to check row constraints
//Code to check col constraints
//Check region constraints (I'm assuming this is to check each subgrid)
int region_size = sqrt(partial_assignment.size());
for (int I = 0; I < region_size; ++I) {
for (int J = 0; J < region_size; ++J) {
if (HasDuplicate(partial_assignment, region_size * I),
region_size * (I + 1), region_size * J,
region_size * (J + 1)){
return false;
}
}
}
return true;
}
//Return true if subarray partial_assignment[start_row : end_row - 1]
//[start_col : end_col -1] contains any duplicates in {1,2,....
// partial_assignment.size()}; otherwise return false.
bool HasDuplicate(const vector<vector<int>>& partial_assignment,
int start_row, int end_row, int start_col, int end_col) {
deque<bool> is_present(partial_assignment.size() + 1, false);
for (int i = start_row; i < end_row;++i) {
for (int j = start_col; j < end_col;++j) {
if (partial_assignment[i][j] != 0 &&
is_present[partial_assignment[i][j]) {
return true;
}
is_present[partial_assignment[i][j]] = true;
}
}
return false;
}
所以我在这里有几个问题:如果它在矩阵中找到了区域(或子方格),为什么需要为该子方格中的每个元素调用has_duplicates()
?我认为你只需要迭代该方块中的每个元素,然后检查以前是否已经看过每个元素。
我假设输入网格是这样的普通二维网格,但可能情况并非如此:
vector<vector<int>> partial_assignment = { {5,3,4,6,7,8,9,1,2},
{6,7,2,1,9,5,3,4,8},
{1,9,8,3,4,2,5,6,7},
{8,5,9,7,6,1,4,2,3},
{4,2,6,8,5,3,7,9,1},
{7,1,3,9,2,4,8,5,6},
{9,6,1,5,3,7,2,8,4},
{2,8,7,4,1,9,6,3,5},
{3,4,5,2,8,6,1,7,9}
};
另外,当您只使用std::deque
时,使用std::unordered_map
检查重复内容有什么意义?
答案 0 :(得分:1)
如果在矩阵中找到了区域(或子方格),为什么需要为该子方格中的每个元素调用has_duplicates()?
不是。 isValidSudoku
中的循环从0
迭代到region_size - 1
,s从标准sudoko从0
迭代到2
。然后,每个I
和J
乘以region_size
,以获得您的开始和结束行/列:0-2
,3-5
和6-8
。 HasDuplicate
被召唤9次。
通过在每个循环中抛出一堆cout <<
语句来分析代码可能会有所帮助,以便在循环迭代时打印出变量。