题目如下:(链接:题目地址)
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
//输入格式:
[["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]]
解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
看到题的时候,犯了一个大忌,果然好的程序是80/%的思考+20/%的代码,而不是80/%的代码+20/%的bug
话不多说,看代码:
public static void main(String[] args) {
char[][] board = {
{'5','3','.','.','7','.','.','.','.'},
{'6','.','.','1','9','5','.','.','.'},
{'.','9','8','.','.','.','.','6','.'},
{'8','.','.','.','6','.','.','.','3'},
{'4','.','.','8','.','3','.','.','1'},
{'7','.','.','.','2','.','.','.','6'},
{'.','6','.','.','.','.','2','8','.'},
{'.','.','.','4','1','9','.','.','5'},
{'.','.','.','.','8','.','.','7','9'}
};
new Demo26().solveSudoku(board);
}
public void solveSudoku(char[][] board) {
System.out.println("原数独:=====");
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
System.out.print(board[i][j]+" ");
}
System.out.println();
}
while (true){
int isEmpty = 0;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
if (board[i][j] == '.'){
int temp = charge(i, j, board);
if (temp != 0){
board[i][j] = String.valueOf(temp).charAt(0);
}else {
isEmpty++;
}
}
}
}
if (isEmpty == 0){
break;
}
}
System.out.println();
System.out.println("数独解:=====");
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
System.out.print(board[i][j]+" ");
}
System.out.println();
}
}
public int charge(int x,int y, char[][] board){
boolean[] flags = new boolean[10];
for (int i = 0; i < board[x].length; i++) {
this.kk(x,i,board,flags);
}
for (int i = 0; i < board.length; i++) {
this.kk(i,y,board,flags);
}
if (0<=x && x<=2){
if (0<=y && y<=2){
for (int i = 0; i <= 2 ; i++) {
for (int j = 0; j <= 2 ; j++) {
this.kk(i,j,board,flags);
}
}
}else if (3<=y && y<=5){
for (int i = 0; i <= 2 ; i++) {
for (int j = 3; j <= 5 ; j++) {
this.kk(i,j,board,flags);
}
}
}else if (6<=y && y<=8){
for (int i = 0; i <= 2 ; i++) {
for (int j = 6; j <= 8 ; j++) {
this.kk(i,j,board,flags);
}
}
}
}else if (3<=x && x<=5){
if (0<=y && y<=2){
for (int i = 3; i <= 5 ; i++) {
for (int j = 0; j <= 2 ; j++) {
this.kk(i,j,board,flags);
}
}
}else if (3<=y && y<=5){
for (int i = 3; i <= 5 ; i++) {
for (int j = 3; j <= 5 ; j++) {
this.kk(i,j,board,flags);
}
}
}else if (6<=y && y<=8){
for (int i = 3; i <= 5 ; i++) {
for (int j = 6; j <= 8 ; j++) {
this.kk(i,j,board,flags);
}
}
}
}else if (6<=x && x<=8){
if (0<=y && y<=2){
for (int i = 6; i <= 8 ; i++) {
for (int j = 0; j <= 2 ; j++) {
this.kk(i,j,board,flags);
}
}
}else if (3<=y && y<=5){
for (int i = 6; i <= 8 ; i++) {
for (int j = 3; j <= 5 ; j++) {
this.kk(i,j,board,flags);
}
}
}else if (6<=y && y<=8){
for (int i = 6; i <= 8 ; i++) {
for (int j = 6; j <= 8 ; j++) {
this.kk(i,j,board,flags);
}
}
}
}
boolean flag = true;
int num = 0,value=0;
for (int i = 1; i <= 9 ; i++) {
if (flags[i]){
num++;
}
}
if (num==8){
for (int i = 1; i <= 9 ; i++) {
if (!flags[i]){
value = i;
}
}
}
return value;
}
public void kk(int x,int y,char[][] board,boolean[] flags){
if (board[x][y] == '1'){
flags[1] = true;
}else if (board[x][y] == '2'){
flags[2] = true;
}else if (board[x][y] == '3'){
flags[3] = true;
}else if (board[x][y] == '4'){
flags[4] = true;
}else if (board[x][y] == '5'){
flags[5] = true;
}else if (board[x][y] == '6'){
flags[6] = true;
}else if (board[x][y] == '7'){
flags[7] = true;
}else if (board[x][y] == '8'){
flags[8] = true;
}else if (board[x][y] == '9'){
flags[9] = true;
}
}
不得不承认,代码着实有点丑陋。。。
解法也是属于最简单最低级的一种,暴力求解,不过结果也满打满算能出来。