//------------------單行數獨------------------ const int N = 9; int M[N] = {0,1,0,3,0,8,0,2,5}; int nHole, hole[N*N]; bool bPack (int n) //是否可將 n 填入 M 裡 { for (int i=0; i<N; i++) //若 M 中已存在 n if (n == M[i]) return false; //則返回 false return true; } void fillHole (int pos) //將 M 中的空位填滿 { int i, x; if (pos == nHole) { //若空位皆已填滿 for (i=0; i<N; i++) cout << M[i]; //便印出解答 puts(""); return; //然後返回 } for (i=1; i<=N; i++) { //嘗試在 M[x] 處填入 1~N x = hole[pos]; //取得空洞位置 if (bPack (i)) { //若可用 i 填起來 M[x] = i; //就令 M[x] = i fillHole (pos+1); //繼續填下一個洞 M[x] = 0; //將 M[x] 還原, 待以用 } //其他值去嘗試填入 } } int main() { for (int i=0; i<N; i++) if (0==M[i]) //將 M 中 0 的位置 hole [nHole++] = i; //記錄在 hole 裡 fillHole (0); }
多行的就像這樣....
同理,可擴展至 N*N*N*....N 的解法。
//------------------多行數獨------------------ const int N = 9; int nHole = 0; int hole [N*N]; int M[N][N] = {0,0,4,0,0,8,0,2,5, 2,0,0,0,0,0,9,0,0, 0,0,6,0,0,5,0,0,0, 5,7,0,0,6,0,0,0,0, 1,0,0,0,4,0,0,0,8, 0,0,0,0,2,0,0,3,7, 0,0,0,3,0,0,8,0,0, 0,0,7,0,0,0,0,0,1, 6,2,0,9,0,0,4,0,0}; bool bPack (int x, int y, int n) //是否可將 n 填入 M[y][x] 裡 { for (int i=0; i<N; i++) //若 M[0~N-1][x] if (n == M[i][x] || n == M[y][i]) //或 M[y][0~N-1] 中已存在 n return false; //則返回 false return true; } void fillHole (int pos) //將 M 中的空位填滿 { int i, x, y; if (pos == nHole) { //若空位皆已填滿 for (i=0; i<N*N; i++) { //便印出解答 if (0 == i%N) puts(""); //每印 N 個就換行 cout << M[0][i]; } puts(""); getch(); return; //然後返回 } for (i=1; i<=N; i++) { //嘗試在 M[y][x] 處填入 1~N y = (x=hole[pos]) / N; //取得空洞位置 y 座標 x %= N; //取得空洞位置 x 座標 if (bPack (x,y,i)) { //若 M[y][x] 可用 i 填起來 M[y][x] = i; //就令 M[y][x] = i fillHole (pos+1); //繼續填下一個洞 M[y][x] = 0; //將 M[y][x] 還原, } //待以用其他值去嘗試填入 } } int main () { for (int i=0; i<N*N; i++) if (0 == M[0][i]) //將 M 中 0 的位置 hole [nHole++] = i; //記錄在 hole 裡 fillHole (0); }
沒有留言:
張貼留言