代碼注釋如下
#include <iostream>
using namespace std;
const int N = 10;
bool col[N][N], rol[N][N], cell[3][3][N];
char g[N][N];
bool dfs(int x, int y) { //用bool這樣在找到一個方案就可以迅速退出if(y == 9) x++, y = 0; //若y超出邊界,則第二行開始y = 0,x++if(x == 9) {for(int i = 0; i < 9; i++) cout << g[i] << endl;return true;//這里返回true讓下面for里面中間的dfs直接結束,不在回溯,少枚舉很多情況//并且是輸出唯一解}if(g[x][y] != '.') return dfs(x, y + 1);//g[x][y] == '.'for(int i = 0; i < 9; i++) {if(!col[y][i] && !rol[x][i] && !cell[x / 3][y / 3][i]) {g[x][y] = i + '1';col[y][i] = rol[x][i] = cell[x / 3][y / 3][i] = true;if(dfs(x, y + 1)) return true;//剪枝,dfs返回值是true上面輸出了答案,不用再回溯,并且//這一枝遞歸直接結束。//恢復操作g[x][y] = '.';col[y][i] = rol[x][i] = cell[x / 3][y / 3][i] = false;}}return false;//如果某個方案失敗,需要返回false讓上面回溯//不加這個也不會輸出結果,因為如果這一枝遞歸沒成功,返回false上面才能回溯
}
int main() {for(int i = 0; i < 9; i++) { cin >> g[i];for(int j = 0; j < 9; j++) {if(g[i][j] != '.') {int x = g[i][j] - '1'; //1-9映射到0-8(方便cell的下取整操作)rol[i][x] = true;col[j][x] = true;cell[i / 3][j / 3][x] = true;}} }dfs(0, 0);return 0;
}
補充
//這樣寫也是對的,只不過沒有剪枝,時間復雜度高些
bool dfs(int x, int y)
{if (y == 9) x ++, y = 0;if (x == 9){for (int i = 0; i < 9; i ++ ) cout << g[i] << endl;return true;}if (g[x][y] != '.') return dfs(x, y + 1);for (int i = 0; i < 9; i ++ )if (!row[x][i] && !col[y][i] && !cell[x / 3][y / 3][i]){g[x][y] = i + '1';row[x][i] = col[y][i] = cell[x / 3][y / 3][i] = true;dfs(x, y + 1);//不同點row[x][i] = col[y][i] = cell[x / 3][y / 3][i] = false;g[x][y] = '.';}//沒有返回值
}