数独问题
一、問題簡介
你一定聽說過“數獨”游戲。
如【圖1.png】,玩家需要根據9×9盤面上的已知數字,推理出所有剩余空格的數字,并滿足每一行、每一列、每一個同色九宮內的數字均含1-9,不重復。
數獨的答案都是唯一的,所以,多個解也稱為無解。
本圖的數字據說是芬蘭數學家花了3個月的時間設計出來的較難的題目。但對會使用計算機編程的你來說,恐怕易如反掌了。
本題的要求就是輸入數獨題目,程序輸出數獨的唯一解。我們保證所有已知數據的格式都是合法的,并且題目有唯一的解。
格式要求,輸入9行,每行9個字符,0代表未知,其它數字為已知。
輸出9行,每行9個數字表示數獨的解。
例如:
輸入(即圖中題目):
005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700
程序應該輸出:
145327698
839654127
672918543
496185372
218473956
753296481
367542819
984761235
521839764
二、思路分析
題目中有四個篩選條件即
1、每行不能含有重復的數字
2、每列不能含有重復的數字
3、每個小的九宮格不能有重復的數字。
4、每個格子的值在1-9之間
為此先創建四個二維數組
1、s數組用于存儲剛開始時從控制臺出入的矩陣
2、rol[i][x]==1代表第i行已存在數字x,那么rol[i][x]==0代表第i行不存在數字x
3、col[j][x]==1代表第j行已存在數字x,那么col[j][x]==0代表第j行不存在數字x
4、small[j/3+i/3*3][x]=1代表第(j/3+i/3*3)個九宮格(從左到右,從上到下)已存在數字x,small[j/3+i/3*3][x]=0代表第(j/3+i/3*3)個九宮格(從左到右,從上到下)不已存在數字x
(PS:j/3+i/3*3是為了判斷i行,j列是屬于哪個九宮格,找幾個位置代入就知道為何如此寫。)
創建這些數組是為了在向s數組的某位置插入數字時,根據另外三個數組來判斷是否可以在此位置插入該數字,
因此在對s數組進行初始化,即接受控制臺上的矩陣時,就要對另外三個數組進行初始化,它們起標志作用。
從棋盤的左上角開始,判斷此處是否可以插入數字,如果可以就插入一個數字,然后跳到下一列,如果到了最后一列,便跳到下一行,每到一個位置便插入一個數字,如果該數字不滿足條件,便換一個數字,然后向下,若所有數字都試過了還不行,便回退到上一個位置,更換上一個位置的數字,然后再向下運行,如此反復,最終只有是滿足條件的數字才能走到最后,也就是說走到最后的便是正確答案。
三、解決代碼
public class Demo6 {static int s[][] = new int[9][9];static int rol[][] = new int[9][10];static int col[][] = new int[9][10];static int small[][] = new int[9][10];public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String[] line = new String[9];for (int i = 0; i < 9; i++) {line[i] = scanner.nextLine();}char[][] c = new char[9][9];for (int i = 0; i < 9; i++) {c[i] = line[i].toCharArray();}for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {s[i][j] = Integer.parseInt(c[i][j] + "");if (s[i][j] != 0) {//在接受控制臺上的矩陣時,就對另外三個數組進行初始化rol[i][s[i][j]] = 1;col[j][s[i][j]] = 1;small[j / 3 + i / 3 * 3][s[i][j]] = 1;}}}getResult(0, 0);//從0行0列開始}public static void getResult(int rolIndex, int colIndex) {if (rolIndex == 9 && colIndex == 0) {//找到答案// 輸出答案for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {System.out.print(s[i][j]);}System.out.println();}}if (rolIndex < 9) {//未找到答案if (s[rolIndex][colIndex] != 0) {if (colIndex == 8) {// 到最后一列,另起一行getResult(rolIndex + 1, 0);} else {// 到下一列getResult(rolIndex, colIndex + 1);}} else {for (int x = 1; x <= 9; x++) {//篩選條件if (col[colIndex][x] != 0 || rol[rolIndex][x] != 0|| small[colIndex / 3 + rolIndex / 3 * 3][x] != 0) {continue;//說明不能插入當前數x,結束本次循環}s[rolIndex][colIndex] = x;rol[rolIndex][x] = 1;col[colIndex][x] = 1;small[colIndex / 3 + rolIndex / 3 * 3][x] = 1;if (colIndex == 8) {getResult(rolIndex + 1, 0);//進入下一行} else {getResult(rolIndex, colIndex + 1);//進入下一列}//----------------------------------------//到這一步說明這個x不能滿足需要,backs[rolIndex][colIndex] = 0;rol[rolIndex][x] = 0;col[colIndex][x] = 0;//前面進行了賦值,這里撤回small[colIndex / 3 + rolIndex / 3 * 3][x] = 0;}}}}}Rome is not built in a day.
總結
- 上一篇: 通讯录_通讯录拦截防爆
- 下一篇: centos 7 防火墙和端口配置