数独程序求解世界最难数独——JAVA版

号称世界最难的数独

在这里插入图片描述

程序源码

import java.util.ArrayList;
import java.util.HashSet;

public class Main {
    private static final int MAX_GUESS_COUNT = 4096;
    private static int guessCount = 0;

    private static long startTime;

    private static void guessOneUnit(Sudoku sudoku) {
        if (++guessCount > MAX_GUESS_COUNT) {
            System.err.println("sudoku can't find the answer after " + guessCount + " times' guess so have to exit");
            sudoku.printEx(true);

            long endTime = System.currentTimeMillis();
            System.out.println("sudoku costs " + (endTime - startTime) + "ms to analyze this problem");
            System.exit(-1);
        }

        Sudoku.UnitToGuess unitToGuess = sudoku.fetchOneUnitToGuess();
        if (unitToGuess == null) {
            sudoku.printEx(true);
            System.err.println("sudoku enter a impossible situation and has to exit");
            return;
        }

        for (Integer e : unitToGuess.getOnes()) {
            Sudoku sudokuNew = sudoku.clone();
            sudokuNew.setOneUnit(unitToGuess.getRowIndex(), unitToGuess.getColIndex(), e);
            sudokuNew.printEx(true);
            if (sudokuNew.setUnitLoop()) {
                guessOneUnit(sudokuNew);
            }
        }
    }

    public static void solve(String input) {
        String[] lines = input.split("\\n");
        int[][] matrix = new int[Sudoku.LINE_UNIT_COUNT][Sudoku.LINE_UNIT_COUNT];
        for (int i = 0; i < Sudoku.LINE_UNIT_COUNT; ++i) {
            String[] units = lines[i].split(",");
            for (int j = 0; j < Sudoku.LINE_UNIT_COUNT; ++j) {
                matrix[i][j] = Integer.parseInt(units[j]);
            }
        }

        Sudoku sudoku = new Sudoku(matrix);
        sudoku.print("----------------original sudo matrix----------------");

        sudoku.initArray();
        sudoku.printEx(true);

        sudoku.setUnitLoop();
        guessOneUnit(sudoku);
    }

    public static class Sudoku implements Cloneable {
        public static final int LINE_MATRIX_UNIT_COUNT = 3;
        public static final int MATRIX_LINT_UNIT_COUNT = LINE_MATRIX_UNIT_COUNT;
        public static final int LINE_MATRIX_COUNT = LINE_MATRIX_UNIT_COUNT;
        public static final int MATRIX_UNIT_COUNT = LINE_MATRIX_UNIT_COUNT * LINE_MATRIX_UNIT_COUNT;
        public static final int LINE_UNIT_COUNT = MATRIX_UNIT_COUNT;

        public static final int PRINT_STEP_COUNT = 2000;

        private int[][] matrix;
        private ArrayList<Integer>[][] matrixEx;

        private HashSet<Integer>[] matrixRow;
        private HashSet<Integer>[] matrixCol;

        private HashSet<Integer>[][] matrixBlocks;

        private int finish;
        private int effective;
        private int empty;

        private static int index = 0;

        public Sudoku() {
            this(new int[LINE_UNIT_COUNT][LINE_UNIT_COUNT]);
        }

        public Sudoku(int[][] matrix) {
            this.finish = 0;
            this.effective = 0;
            this.empty = LINE_UNIT_COUNT * LINE_UNIT_COUNT;

            this.matrix = new int[LINE_UNIT_COUNT][LINE_UNIT_COUNT];
            this.matrixEx = new ArrayList[LINE_UNIT_COUNT][LINE_UNIT_COUNT];

            this.matrixRow = new HashSet[LINE_UNIT_COUNT];
            this.matrixCol = new HashSet[LINE_UNIT_COUNT];

            this.matrixBlocks = new HashSet[LINE_MATRIX_COUNT][LINE_MATRIX_COUNT];

            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    this.matrix[i][j] = matrix[i][j];
                    this.matrixEx[i][j] = new ArrayList<>();
                    if (matrix[i][j] != 0) {
                        --this.empty;
                        ++this.finish;
                    }
                }
            }

            for (int k = 0; k < LINE_UNIT_COUNT; ++k) {
                matrixRow[k] = new HashSet<>();
                matrixCol[k] = new HashSet<>();
            }

            for (int i = 0; i < LINE_MATRIX_COUNT; ++i) {
                for (int j = 0; j < LINE_MATRIX_COUNT; ++j) {
                    matrixBlocks[i][j] = new HashSet<>();
                }
            }
        }

        public Sudoku clone() {
            Sudoku sudoku = new Sudoku();

            sudoku.empty = empty;
            sudoku.effective = effective;
            sudoku.finish = finish;

            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    sudoku.matrix[i][j] = matrix[i][j];
                    for (Integer e : matrixEx[i][j]) {
                        sudoku.matrixEx[i][j].add(e);
                    }
                }
            }

            for (int k = 0; k < LINE_UNIT_COUNT; ++k) {
                for (Integer e : matrixRow[k]) {
                    sudoku.matrixRow[k].add(e);
                }

                for (Integer e : matrixRow[k]) {
                    sudoku.matrixRow[k].add(e);
                }
            }

            for (int i = 0; i < LINE_MATRIX_COUNT; ++i) {
                for (int j = 0; j < LINE_MATRIX_COUNT; ++j) {
                    for (Integer e : matrixBlocks[i][j]) {
                        sudoku.matrixBlocks[i][j].add(e);
                    }
                }
            }

            return sudoku;
        }

        private ArrayList<Integer> getInitUnit() {
            ArrayList<Integer> unit = new ArrayList<>();
            for (int i = 1; i <= LINE_UNIT_COUNT; ++i) {
                unit.add(i);
            }
            return unit;
        }

        private ArrayList<Integer> getInitUnitWithValue(int i) {
            ArrayList<Integer> unit = new ArrayList<>();
            unit.add(i);
            return unit;
        }

        private void initArray() {
            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    if (matrix[i][j] != 0) {
                        matrixEx[i][j] = getInitUnitWithValue(matrix[i][j]);
                        matrixRow[i].add(matrix[i][j]);
                        matrixCol[j].add(matrix[i][j]);
                        matrixBlocks[i / LINE_MATRIX_UNIT_COUNT][j / LINE_MATRIX_UNIT_COUNT].add(matrix[i][j]);
                    }
                }
            }

            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    if (matrix[i][j] == 0) {
                        matrixEx[i][j] = getInitUnit();
                    }
                }
            }
        }

        private void print(String title) {
            System.out.println(title);
            System.out.println("empty:" + empty + ",finish:" + finish + ",effective:" + effective);

            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    if (matrix[i][j] != 0) {
                        stringBuilder.append(" ").append(matrix[i][j]).append(" ");
                    } else {
                        stringBuilder.append("   ");
                    }

                    if (j != LINE_UNIT_COUNT - 1) {
                        if (j % 3 == 2) {
                            stringBuilder.append('║');
                        } else {
                            stringBuilder.append('│');
                        }
                    }
                }
                stringBuilder.append(System.lineSeparator());
                if (i != LINE_UNIT_COUNT - 1) {
                    boolean isDouble = i % 3 == 2;
                    printRowLine(isDouble, stringBuilder);
                }
            }

            stringBuilder.append(System.lineSeparator());
            System.out.println(stringBuilder);
        }

        private void printRowLine(boolean isDouble, StringBuilder stringBuilder) {
            String edge;
            char cross1;
            char cross2;
            if (isDouble) {
                edge = "═══";
                cross1 = '╪';
                cross2 = '╬';
            } else {
                edge = "───";
                cross1 = '┼';
                cross2 = '╫';
            }

            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                stringBuilder.append(edge);

                if (i != LINE_UNIT_COUNT - 1) {
                    if (i % LINE_MATRIX_UNIT_COUNT == 2) {
                        stringBuilder.append(cross2);
                    } else {
                        stringBuilder.append(cross1);
                    }
                }
            }

            stringBuilder.append(System.lineSeparator());
        }

        private void printEx(boolean force) {
            if (!force && ++index % PRINT_STEP_COUNT != 0) {
                return;
            }

            System.out.println("this is the " + index + "'th loop result");
            System.out.println("empty:" + empty + ",finish:" + finish + ",effective:" + effective);

            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int l = 0; l < MATRIX_LINT_UNIT_COUNT; ++l) {
                    for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                        for (int k = 0; k < MATRIX_LINT_UNIT_COUNT; ++k) {
                            int n = l * MATRIX_LINT_UNIT_COUNT + k + 1;

                            if (matrixEx[i][j].contains(n)) {
                                stringBuilder.append(" ").append(n).append(" ");
                            } else {
                                stringBuilder.append("   ");
                            }

                        }
                        if (j != LINE_UNIT_COUNT - 1) {
                            if (j % 3 == 2) {
                                stringBuilder.append('║');
                            } else {
                                stringBuilder.append('│');
                            }
                        }
                    }
                    stringBuilder.append(System.lineSeparator());
                }

                if (i != LINE_UNIT_COUNT - 1) {
                    boolean isDouble = i % 3 == 2;
                    printRowLineEx(isDouble, stringBuilder);
                }
            }
            stringBuilder.append(System.lineSeparator());
            System.out.println(stringBuilder);
        }

        private void printRowLineEx(boolean isDouble, StringBuilder stringBuilder) {
            String edge;
            char cross1;
            char cross2;
            if (isDouble) {
                edge = "═══";
                cross1 = '╪';
                cross2 = '╬';
            } else {
                edge = "───";
                cross1 = '┼';
                cross2 = '╫';
            }

            for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                for (int k = 0; k < LINE_MATRIX_UNIT_COUNT; ++k) {
                    stringBuilder.append(edge);
                }
                if (j != LINE_UNIT_COUNT - 1) {
                    if (j % LINE_MATRIX_UNIT_COUNT == 2) {
                        stringBuilder.append(cross2);
                    } else {
                        stringBuilder.append(cross1);
                    }
                }
            }

            stringBuilder.append(System.lineSeparator());
        }

        private void finish() {
            print("sudoku has find one answer showed followed so will exit normally");
            long endTime = System.currentTimeMillis();
            System.out.println("sudoku costs " + (endTime - startTime) + "ms to analyze this problem");
            System.exit(0);
        }

        public static class UnitToGuess {
            private int rowIndex;
            private int colIndex;

            private ArrayList<Integer> ones = new ArrayList<>();

            public int getRowIndex() {
                return rowIndex;
            }

            public int getColIndex() {
                return colIndex;
            }

            public ArrayList<Integer> getOnes() {
                return ones;
            }

            public UnitToGuess(int rowIndex, int colIndex, ArrayList<Integer> ones) {
                this.rowIndex = rowIndex;
                this.colIndex = colIndex;
                for (Integer e : ones) {
                    this.ones.add(e);
                }
            }

        }

        private boolean setOneUnit(int rowIndex, int colIndex, int element) {
            System.out.println("try to set unit[" + rowIndex + "," + colIndex + "]=" + element + " for next loop");
            return setUnit(false, rowIndex, colIndex, element);
        }

        public UnitToGuess fetchOneUnitToGuess() {
            int miniSize = MATRIX_UNIT_COUNT;
            int rowIndex = -1;
            int colIndex = -1;

            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    if (matrixEx[i][j].size() > 1 && matrixEx[i][j].size() < miniSize) {
                        rowIndex = i;
                        colIndex = j;
                        miniSize = matrixEx[i][j].size();
                    }
                }
            }

            if (rowIndex != -1 && colIndex != -1) {
                return new UnitToGuess(rowIndex, colIndex, matrixEx[rowIndex][colIndex]);
            }

            return null;
        }

        public boolean setUnitLoop() {
            while (true) {
                int lastEffective = effective;
                if (!setUnitOfOneSize() || !setUnitInBlock() || !setUnitInLine(true) || !setUnitInLine(false)) {
                    printEx(true);
                    return false;
                }

                if (empty == 0) {
                    finish();
                }

                if (effective == lastEffective) {
                    System.out.println("this removeLoop can't remove any more");
                    break;
                }
            }

            return true;
        }

        private ArrayList<Integer> getUnit(boolean revert, int rowIndex, int colIndex) {
            return revert ? matrixEx[colIndex][rowIndex] : matrixEx[rowIndex][colIndex];
        }

        private boolean checkRight() {
            boolean flag = true;
            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    if (matrix[i][j] != 0) {
                        for (int ii = i / LINE_MATRIX_UNIT_COUNT * LINE_MATRIX_UNIT_COUNT;
                             ii < i / LINE_MATRIX_UNIT_COUNT * LINE_MATRIX_UNIT_COUNT + LINE_MATRIX_UNIT_COUNT; ++ii) {
                            for (int jj = j / LINE_MATRIX_UNIT_COUNT * LINE_MATRIX_UNIT_COUNT;
                                 jj < j / LINE_MATRIX_UNIT_COUNT * LINE_MATRIX_UNIT_COUNT + LINE_MATRIX_UNIT_COUNT; ++jj) {
                                if ((i != ii || j != jj) && matrix[i][j] == matrix[ii][jj]) {
                                    System.out.println("[" + i + ',' + j + "]=[" + ii + ',' + jj + "]=" + matrix[i][j]);
                                    flag = false;
                                }
                            }
                        }

                        for (int k = 0; k < LINE_UNIT_COUNT; ++k) {
                            if (i != k && matrix[i][j] == matrix[k][j]) {
                                System.out.println("[" + i + ',' + j + "]=[" + k + ',' + j + "]=" + matrix[i][j]);
                                flag = false;
                            }
                            if (j != k && matrix[i][j] == matrix[i][k]) {
                                System.out.println("[" + i + ',' + j + "]=[" + i + ',' + k + "]=" + matrix[i][j]);
                                flag = false;
                            }
                        }
                    }
                }
            }

            if (!flag) {
                System.out.println("sudoku's first guess is error and will try the other guess again");
                printEx(true);
            }

            return flag;
        }

        private boolean setUnit(boolean revert, int rowIndex, int colIndex, Integer e) {
            int i;
            int j;
            if (revert) {
                i = colIndex;
                j = rowIndex;
            } else {
                i = rowIndex;
                j = colIndex;
            }

            if (matrix[i][j] == 0 && matrixEx[i][j].contains(e)) {
                matrixEx[i][j].clear();
                matrixEx[i][j].add(e);

                matrix[i][j] = e;
                matrixRow[i].add(e);
                matrixCol[j].add(e);
                matrixBlocks[i / LINE_MATRIX_UNIT_COUNT][j / LINE_MATRIX_UNIT_COUNT].add(e);

                --empty;
                ++finish;
                ++effective;

                printEx(false);
                return checkRight();
            }

            return true;
        }

        private boolean setUnitInLine(boolean isRow) {
            boolean revert = !isRow;

            for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                int[] count = new int[LINE_UNIT_COUNT + 1];
                for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                    for (int e : getUnit(revert, i, j)) {
                        count[e]++;
                    }
                }

                ArrayList<Integer> ones = new ArrayList<>();
                for (int k = 1; k <= MATRIX_UNIT_COUNT; ++k) {
                    if (count[k] == 1) {
                        ones.add(k);
                    }
                }

                for (int e : ones) {
                    for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                        boolean flag = setUnit(revert, i, j, e);
                        if (!flag) {
                            return false;
                        }
                    }
                }
            }

            return true;
        }

        private boolean setUnitInBlock() {
            for (int i = 0; i < LINE_MATRIX_COUNT; ++i) {
                for (int j = 0; j < LINE_MATRIX_COUNT; ++j) {
                    int[] count = new int[MATRIX_UNIT_COUNT + 1];
                    for (int ii = 0; ii < LINE_MATRIX_UNIT_COUNT; ++ii) {
                        for (int jj = 0; jj < LINE_MATRIX_UNIT_COUNT; ++jj) {
                            int indexI = i * LINE_MATRIX_UNIT_COUNT + ii;
                            int indexJ = j * LINE_MATRIX_UNIT_COUNT + jj;
                            for (int e : matrixEx[indexI][indexJ]) {
                                count[e]++;
                            }
                        }
                    }
                    ArrayList<Integer> ones = new ArrayList<>();
                    for (int k = 1; k <= MATRIX_UNIT_COUNT; ++k) {
                        if (count[k] == 1) {
                            ones.add(k);
                        }
                    }

                    for (int e : ones) {
                        for (int ii = 0; ii < LINE_MATRIX_UNIT_COUNT; ++ii) {
                            for (int jj = 0; jj < LINE_MATRIX_UNIT_COUNT; ++jj) {
                                int indexI = i * LINE_MATRIX_UNIT_COUNT + ii;
                                int indexJ = j * LINE_MATRIX_UNIT_COUNT + jj;
                                boolean flag = setUnit(false, indexI, indexJ, e);
                                if (!flag) {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }

        private boolean setUnitOfOneSize() {
            for (int i = 0; i < LINE_UNIT_COUNT; ++i) {
                for (int j = 0; j < LINE_UNIT_COUNT; ++j) {
                    if (matrix[i][j] == 0) {
                        if (matrixEx[i][j].removeAll(matrixRow[i]) || matrixEx[i][j].removeAll(matrixCol[j])
                                || matrixEx[i][j].removeAll(matrixBlocks[i / LINE_MATRIX_UNIT_COUNT][j / LINE_MATRIX_UNIT_COUNT])) {
                            if (effective > 1000) {
                                System.out.println("may error occur");
                            }
                            ++effective;
                        }
                        if (matrixEx[i][j].size() == 0) {
                            return false;
                        } else if (matrixEx[i][j].size() == 1) {
                            boolean flag = setUnit(false, i, j, matrixEx[i][j].get(0));
                            if (!flag) {
                                return false;
                            }
                        }
                    }
                }
            }

            return true;
        }
    }


    public static void main(String[] args) {
        startTime = System.currentTimeMillis();
        String input =  "8,0,0,0,0,0,0,0,0\n" +
                        "0,0,3,6,0,0,0,0,0\n" +
                        "0,7,0,0,9,0,2,0,0\n" +
                        "0,5,0,0,0,7,0,0,0\n" +
                        "0,0,0,0,4,5,7,0,0\n" +
                        "0,0,0,1,0,0,0,3,0\n" +
                        "0,0,1,0,0,0,0,6,8\n" +
                        "0,0,8,5,0,0,0,1,0\n" +
                        "0,9,0,0,0,0,4,0,0";
//                "0,0,0,1,0,2,0,0,0\n" +
//                "0,0,8,0,6,0,7,0,5\n" +
//                "0,9,0,0,0,0,0,8,0\n" +
//                "4,0,0,0,1,0,0,0,0\n" +
//                "0,8,0,3,0,4,0,6,0\n" +
//                "3,0,0,0,2,0,8,0,0\n" +
//                "0,6,0,0,0,5,4,7,0\n" +
//                "0,0,5,0,7,0,6,0,9\n" +
//                "0,7,0,0,0,0,0,5,0";
//                        "0,0,0,0,0,2,0,5,0\n" +
//                        "0,7,8,0,0,0,3,0,0\n" +
//                        "0,0,0,0,0,4,0,0,0\n" +
//                        "5,0,0,0,0,0,0,0,0\n" +
//                        "0,0,0,0,0,0,1,0,0\n" +
//                        "0,0,0,0,3,0,7,0,8\n" +
//                        "2,0,0,0,0,0,0,4,0\n" +
//                        "0,0,0,0,0,5,0,9,0\n" +
//                        "0,1,0,0,7,0,0,0,0";
//                "0,0,0,0,0,0,7,0,0\n" +
//                "0,4,0,0,3,0,0,6,5\n" +
//                "0,0,1,0,0,8,0,0,0\n" +
//                "0,6,0,0,5,0,0,3,9\n" +
//                "4,0,0,6,0,0,0,0,0\n" +
//                "0,0,0,0,0,0,0,2,0\n" +
//                "8,0,0,0,0,3,0,9,7\n" +
//                "0,0,0,0,7,0,4,0,0\n" +
//                "0,9,0,0,0,0,2,0,0";
        solve(input);
    }
}

运行结果

... ...

this is the 2068'th loop result
empty:21,finish:60,effective:309
         │ 1       │    2    ║         │         │       3 ║         │         │         
         │         │         ║         │    5    │         ║       6 │ 4       │         
    8    │         │         ║ 7       │         │         ║         │         │       9 
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
         │         │       3 ║         │    2    │         ║ 1       │         │ 1       
         │ 4       │         ║       6 │         │         ║    5    │         │    5    
       9 │         │         ║         │         │    8    ║         │ 7       │         
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
         │         │         ║         │         │ 1       ║    2    │         │       3 
       6 │         │    5    ║ 4       │         │         ║         │         │         
         │ 7       │         ║         │       9 │         ║         │    8    │         
═════════╪═════════╪═════════╬═════════╪═════════╪═════════╬═════════╪═════════╪═════════
 1       │         │         ║    2  3 │       3 │         ║         │    2    │         
         │    5    │ 4     6 ║         │       6 │         ║         │         │ 4     6 
         │         │       9 ║         │    8    │ 7       ║    8    │       9 │         
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
         │       3 │         ║    2  3 │         │         ║         │    2    │ 1       
         │       6 │       6 ║         │ 4       │    5    ║         │         │       6 
         │    8    │       9 ║    8    │         │         ║ 7       │       9 │         
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
    2    │         │         ║ 1       │         │         ║         │       3 │         
         │       6 │ 4     6 ║         │       6 │         ║    5    │         │ 4  5  6 
         │    8    │ 7       ║         │    8    │       9 ║    8    │         │         
═════════╪═════════╪═════════╬═════════╪═════════╪═════════╬═════════╪═════════╪═════════
         │    2    │ 1       ║         │         │         ║       3 │         │         
    5    │         │         ║         │         │ 4       ║         │       6 │         
         │         │         ║       9 │ 7       │         ║         │         │    8    
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
         │       3 │         ║         │       3 │    2    ║         │ 1       │         
 4       │       6 │         ║    5    │       6 │         ║         │         │         
         │         │    8    ║         │         │         ║       9 │         │ 7       
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
       3 │         │         ║         │ 1       │         ║         │         │    2    
         │         │       6 ║         │         │       6 ║ 4       │    5    │         
         │       9 │ 7       ║    8    │         │         ║         │         │         


try to set unit[1,4]=8 for next loop
this is the 2069'th loop result
empty:29,finish:52,effective:291
         │ 1       │    2    ║         │         │       3 ║         │         │         
         │         │         ║         │    5    │         ║       6 │ 4       │         
    8    │         │         ║ 7       │         │         ║         │         │       9 
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
         │         │       3 ║         │         │    2    ║ 1       │         │ 1       
         │ 4       │         ║       6 │         │         ║    5    │         │    5    
       9 │         │         ║         │    8    │    8    ║         │ 7       │         
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
         │         │         ║         │         │ 1       ║    2    │         │       3 
       6 │         │    5    ║ 4       │         │         ║         │         │         
         │ 7       │         ║         │       9 │         ║         │    8    │         
═════════╪═════════╪═════════╬═════════╪═════════╪═════════╬═════════╪═════════╪═════════
 1  2  3 │         │         ║    2  3 │    2  3 │         ║ 1       │    2    │ 1       
         │    5    │ 4     6 ║         │       6 │         ║         │         │ 4     6 
         │         │       9 ║    8    │    8    │ 7       ║    8    │       9 │         
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
 1  2  3 │       3 │         ║    2  3 │         │         ║         │    2    │ 1       
         │       6 │       6 ║         │ 4       │    5    ║         │         │       6 
         │    8    │       9 ║    8    │         │         ║ 7       │       9 │         
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
    2    │         │         ║ 1       │    2    │         ║         │       3 │         
         │       6 │ 4     6 ║         │       6 │         ║    5    │         │ 4  5  6 
 7       │    8    │ 7       ║         │    8    │       9 ║    8    │         │         
═════════╪═════════╪═════════╬═════════╪═════════╪═════════╬═════════╪═════════╪═════════
         │    2    │ 1       ║         │         │         ║       3 │         │         
    5    │         │         ║         │         │ 4       ║         │       6 │         
         │         │         ║       9 │ 7       │         ║         │         │    8    
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
         │       3 │         ║         │    2  3 │    2    ║         │ 1       │         
 4       │       6 │         ║    5    │       6 │       6 ║         │         │         
         │         │    8    ║         │         │         ║       9 │         │ 7       
─────────┼─────────┼─────────╫─────────┼─────────┼─────────╫─────────┼─────────┼─────────
       3 │         │         ║       3 │ 1       │         ║         │         │    2    
         │         │       6 ║         │         │       6 ║ 4       │    5    │         
 7       │       9 │ 7       ║    8    │         │    8    ║         │         │         


sudoku has find one answer showed followed so will exit normally
empty:0,finish:81,effective:343
 8 │ 1 │ 2 ║ 7 │ 5 │ 3 ║ 6 │ 4 │ 9 
───┼───┼───╫───┼───┼───╫───┼───┼───
 9 │ 4 │ 3 ║ 6 │ 8 │ 2 ║ 1 │ 7 │ 5 
───┼───┼───╫───┼───┼───╫───┼───┼───
 6 │ 7 │ 5 ║ 4 │ 9 │ 1 ║ 2 │ 8 │ 3 
═══╪═══╪═══╬═══╪═══╪═══╬═══╪═══╪═══
 1 │ 5 │ 4 ║ 2 │ 3 │ 7 ║ 8 │ 9 │ 6 
───┼───┼───╫───┼───┼───╫───┼───┼───
 3 │ 6 │ 9 ║ 8 │ 4 │ 5 ║ 7 │ 2 │ 1 
───┼───┼───╫───┼───┼───╫───┼───┼───
 2 │ 8 │ 7 ║ 1 │ 6 │ 9 ║ 5 │ 3 │ 4 
═══╪═══╪═══╬═══╪═══╪═══╬═══╪═══╪═══
 5 │ 2 │ 1 ║ 9 │ 7 │ 4 ║ 3 │ 6 │ 8 
───┼───┼───╫───┼───┼───╫───┼───┼───
 4 │ 3 │ 8 ║ 5 │ 2 │ 6 ║ 9 │ 1 │ 7 
───┼───┼───╫───┼───┼───╫───┼───┼───
 7 │ 9 │ 6 ║ 3 │ 1 │ 8 ║ 4 │ 5 │ 2 


sudoku costs 128ms to analyze this problem

进程已结束,退出代码0

答案

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值