數獨概念,思路,解法思路,C++code
該部落格整體代碼的思路十分的清晰,值得借鑒。
上述部落格當中的代碼dfs知識輸出的一種數組的答案,如果該數專屬多中解法的話,只需將dfs的代碼簡單改動即可(如下):
void dfs(int row,int col){ if (row>9) //如果行超出9行,直接輸出 { for (int i=1; i<=9; i++) { for (int j=1; j<=9; j++) { printf("%d",a[i][j]); (j == 9)? cout << "": cout <<" "; } printf("\n"); } cout << "***************************************\n"; //exit(0);// 經參數返回給作業系統,0 表示正常結束,非零表示不正常結束。 return ; } if (a[row][col]==0) //如果沒有填數字 { for (int i=1; i<=9; i++) { if (is_row_col_repeat(row, col, i) && is_block_repeat(row, col, i)) //如果行列九宮格不重複 { a[row][col]=i;//填充數字 dfs(row+(col+1)/10, (col <= 8)? col+1 : 1);//繼續搜尋 a[row][col]=0;//重新置為0 } } //a[row][col]=0;//重新置為0 } else //如果已經填了,繼續搜尋 { dfs(row+(col+1)/10, (col <= 8)? col+1 : 1); }}
整體代碼如下:
#include <bits/stdc++.h>using namespace std;int a[10][10];//儲存數字int is_row_col_repeat(int row,int col,int num) //判斷行列是否重複{ //判斷行是否重複 for (int i=1; i<=9; i++) { if (a[row][i]==num) { return 0;//行重複,返回0 } } //判斷列是否重複 for (int i=1; i<=9; i++) { if (a[i][col]==num) { return 0;//列重複,返回0 } } return 1;//行列不重複,返回1}int check_row_range(int row) //判斷行的範圍{ if (row>=1 && row<=3) { return 1; } else if(row>=4&&row<=6) { return 4; } else { return 7; }}int check_col_range(int col) //判斷列的範圍{ if(col>=1&&col<=3) { return 1; } else if (col>=4&&col<=6) { return 4; } else { return 7; }}int is_block_repeat(int row,int col,int num) //判斷同色九宮格是否重複{ int x,y; x=check_row_range(row); y=check_col_range(col); for (int i=x; i<=x+2; i++) { for (int j=y; j<=y+2; j++) { if (a[i][j]==num) { return 0;//重複,返回0 } } } return 1;//不重複,返回1}void dfs(int row,int col){ if (row>9) //如果行超出9行,直接輸出 { for (int i=1; i<=9; i++) { for (int j=1; j<=9; j++) { printf("%d",a[i][j]); (j == 9)? cout << "": cout <<" "; } printf("\n"); } cout << "***************************************\n"; //exit(0); return ; } if (a[row][col]==0) //如果沒有填數字 { for (int i=1; i<=9; i++) { if (is_row_col_repeat(row, col, i) && is_block_repeat(row, col, i)) //如果行列九宮格不重複 { a[row][col]=i;//填充數字 dfs(row+(col+1)/10, (col <= 8)? col+1 : 1);//繼續搜尋 a[row][col]=0;//重新置為0 } } //a[row][col]=0;//重新置為0 } else //如果已經填了,繼續搜尋 { dfs(row+(col+1)/10, (col <= 8)? col+1 : 1); }}int main(int argc, char *argv[]){ string s; for(int i=1; i<=9; i++) { cin >> s;//輸入字串 for(int j=1; j<=9; j++) { char ss=s.at(j-1);//取s的第j-1的字元 a[i][j]=ss-'0';//將ss轉化為整數 } } dfs(1,1); return 0;}
上述代碼看著挺長的,我試著壓縮了一下,感覺沒有那麼難看,而且也沒有那麼長了
#include <bits/stdc++.h>using namespace std;const int N = 10;int a[N][N];int is_row_col_repeat(int row, int col, int num){ for(int i = 1; i <= 9; i++) if(a[row][i] == num || a[i][col] == num) return 0; return 1;}int check_row_range(int row){ if(row >= 1 && row <= 3) return 1; else if(row >= 4 && row <= 6) return 4; else return 7;}int check_col_range(int col){ if(col >= 1 && col <= 3) return 1; else if(col >= 4 && col <= 6) return 4; else return 7;}int is_block_repeat(int row, int col, int num){ int x = check_row_range(row); int y = check_col_range(col); for(int i = x; i <= x+2; i++) for(int j = y; j <= y+2; j++) if(a[i][j] == num) return 0; return 1;}void output(){ for(int i = 1; i <= 9; i++) for(int j = 1; j <= 9; j++) cout << a[i][j], (j <= 8)? printf(" "): putchar('\n'); printf("************************\n");}void dfs(int row, int col){ if(row > 9) output(), exit(0); if(a[row][col] == 0) for(int i = 1; i <= 9; i++) if(is_row_col_repeat(row, col, i) && is_block_repeat(row, col, i)) { a[row][col] = i; dfs(row + (col+1) / 10, (col <= 8)? col+1 : 1); a[row][col] = 0; } if(a[row][col] != 0) dfs( row + (col+1) / 10, (col <= 8)? col+1 : 1 );}int main(){ string s; for(int i = 1; i <= 9; i++) { cin >> s; for(int j = 1; j <= 9; j++) { char ss = s.at(j - 1); a[i][j] = ss - '0'; } } dfs(1, 1); return 0;}