查找数量可能的解决方案Sudoku Java

时间:2016-04-25 16:45:53

标签: java sudoku backtracking

我正在尝试找到数独的可能解决方案,它总是告诉我:0。

我必须用回溯来做,我不知道问题出在哪里,这是代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class PracticaDAA3 {

    public static boolean Cumple(int[][] matriz, int numero, int[] posicion) {
        int x = posicion[0];
        int y = posicion[1];
        for (int i = 0; i < 9; i++) {
            if (matriz[i][y] == numero) {
                return false;
            }
        }
        for (int j = 0; j < 9; j++) {
            if (matriz[x][j] == numero) {
                return false;
            }
        }
        if (x < 3 && y < 3) {
            for (int k = 0; k < 3; k++) {
                for (int l = 0; l < 3; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x > 2 && x < 6 && y < 3) {
            for (int k = 3; k < 6; k++) {
                for (int l = 0; l < 3; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x > 5 && y < 3) {
            for (int k = 6; k < 9; k++) {
                for (int l = 0; l < 3; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x < 3 && y > 2 && y < 6) {
            for (int k = 0; k < 3; k++) {
                for (int l = 3; l < 6; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x > 2 && x < 6 && y > 2 && y < 6) {
            for (int k = 3; k < 6; k++) {
                for (int l = 3; l < 6; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x > 5 && y > 2 && y < 6) {
            for (int k = 6; k < 9; k++) {
                for (int l = 3; l < 6; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x < 3 && y > 5) {
            for (int k = 0; k < 3; k++) {
                for (int l = 6; l < 9; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x > 2 && x < 6 && y > 5) {
            for (int k = 3; k < 6; k++) {
                for (int l = 6; l < 9; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        } else if (x > 5 && y > 5) {
            for (int k = 6; k < 9; k++) {
                for (int l = 6; l < 9; l++) {
                    if (matriz[k][l] == numero) {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    public static void siguientePosicion(int[] xy) {
        int x = xy[0];
        int y = xy[1];
        //if(x<9 && y<9){
        if (y == 8) {
            xy[1] = 0;
            xy[0]++;
            //System.out.println("xy0: "+xy[0]+" xy1: "+xy[1]);
        } else
            xy[1]++;

    }

    public static void ResolSudoku(int[] xy, int[][] matriz, int[] solucion) {
        int x = xy[0];
        int y = xy[1];
        if (x < 9 && y < 9) {
            if (matriz[x][y] == 0) {      //entramos por aqui si hay un 0
                for (int i = 1; i < 10; i++) {
                    if (Cumple(matriz, i, xy)) { //aqui compruebo si mifila o columna o matriz tiene un nº
                        matriz[x][y] = i;
                        //System.out.println("xy0: "+xy[0]+" xy1: "+xy[1]);
                        if (x == 8 && y == 8)
                            solucion[0]++;
                        else {
                            int[] xy2 = new int[2];
                            xy2[0] = x;
                            xy2[1] = y;
                            siguientePosicion(xy2);
                            ResolSudoku(xy2, matriz, solucion);
                        }
                        matriz[x][y] = 0;
                    }
                }
            } else {
                siguientePosicion(xy);
                // System.out.println("X: "+x);
                //System.out.println("x,y: "+x+y);
                ResolSudoku(xy, matriz, solucion);
            }
        }
    }

    /**
     * @param args the command line arguments
     * @throws java.io.IOException
     */
    public static void Imprimir(int[][] m) {
        for (int i = 0; i < 9; i++) {
            System.out.println();
            for (int j = 0; j < 9; j++) {
                System.out.print(m[i][j] + " ");

            }
        }
    }

    public static void main(String[] args) throws IOException {
        int[][] matriz = new int[9][9];
        int[] xy = new int[2];
        xy[0] = 0;
        xy[1] = 0;
        BufferedReader entrada = new BufferedReader(new InputStreamReader(System.in));
        for (int i = 0; i < 9; ++i) {
            String[] lista = entrada.readLine().split(" ");
            for (int j = 0; j < 9; j++) {
                matriz[i][j] = Integer.parseInt(lista[j]);
            }
        }
        int[] solucion = new int[1];
        solucion[0] = 0;
        ResolSudoku(xy, matriz, solucion);
        System.out.println(solucion[0]);
        Imprimir(matriz);
    }

}

我知道这个输入:

5 3 4 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9

输出必须为1,但结果为0。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

问题是,如果matriz[x][y]中的数字为零,则只检查您是否有有效的解决方案。在您的示例谜题中,matriz[8][8]9,因此当if (x == 8 && y == 8) {x都是y时,您的代码永远不会到达8行。

基本上,您有这个if语句(代码替换为注释):

    if (matriz[x][y] == 0) {   
        // Check to see what numbers fit here.  For each number that fits here, check
        // to see if we're at the last grid cell.  If so, record a solution, otherwise
        // move to the next grid cell.
    }
    else {
        // Move to the next grid cell.
    }

修复方法是用以下内容替换else子句:

    else {
        // Check to see if we're at the last grid cell.  If so, record a solution, 
        // otherwise move to the next grid cell.
    }