最近在nds上下了个激辣数独的游戏,结果简单的难度的第一关就玩不过去……
自信心严重受打击,郁闷非常。于是写了这个递归的函数找答案……
答案是出来了,但是心里还是不爽啊,下次要写个正常思路下的解决方法来才行!
import java.util.HashSet;
import java.util.Set;

public class SudoKuRecursion {
   private int[][] origin;
   private int[][] result;
   private boolean isResolved;

   public SudoKuRecursion( final int[][] iS) {
    origin = copySudoku(iS);
    isResolved = false;
  }

   private int[][] copySudoku( final int[][] origin) {
     int[][] dest;
     if (origin.length != 9) {
       throw new RuntimeException( "range error");
    }
    dest = new int[9][];
     for ( int i = 0; i < 9; i++) {
       if (origin[i].length != 9) {
         throw new RuntimeException( "range error");
      }
      dest[i] = new int[9];
       for ( int j = 0; j < 9; j++) {
        dest[i][j] = origin[i][j];
      }
    }
     return dest;
  }

   // 1=right here
   // 0=maybe
   // -1=wrong
   private int check( final int[][] origin, final int x, final int y, final int value) {
     if (origin.length > 9 || x < 0 || x > 8 || y < 0 || y > 8 || value < 1 || value > 9) {
       throw new RuntimeException( "range");
    }
     int lx = x / 3;
    lx = lx * 3;
     int ly = y / 3;
    ly = ly * 3;
    Set<Integer> s = new HashSet<Integer>();
     for ( int i = 0; i < 9; i++) {
       if (i != y) {
         if (origin[x][i] == value) {
           return -1;
        } else {
          s.add(origin[x][i]);
        }
      }
       if (i != x) {
         if (origin[i][y] == value) {
           return -1;
        } else {
          s.add(origin[i][y]);
        }
      }

       int tx = lx + ( int) (i / 3);
       int ty = ly + ( int) (i % 3);
       if (tx != x && ty != y) {
         if (origin[tx][ty] == value) {
           return -1;
        } else {
          s.add(origin[tx][ty]);
        }
      }
    }
    s.remove(0);
     if (s.size() == 8) {
       return 1;
    } else {
       return 0;
    }
  }

   private void printSuduku( final int[][] sudoku) {
    System.out.println( "----------------------------------");
     for ( int i = 0; i < 9; i++) {
       for ( int j = 0; j < 9; j++) {
        System.out.print(sudoku[i][j] + " ");
      }
      System.out.println();
    }
  }

   public void printResult() {
     if (isResolved) {
      System.out.println( "original sudoku:");
      printSuduku(origin);
      System.out.println( "result:");
      printSuduku(result);
    } else {
      System.out.println( "not resolved.");
    }
  }

   private void verifySudoku( int[][] origin, final int x, final int y) {

     if (origin[x][y] == 0) {
       for ( int i = 1; i < 10; i++) {
         int r = check(origin, x, y, i);
         if (r == 1) {

          origin[x][y] = i;

           if (x == 8 && y == 8) {
            result = copySudoku(origin);
            isResolved = true;
             break;
          }
           int nx = (y == 8 ? x + 1 : x);
           int ny = (y == 8 ? 0 : y + 1);
          verifySudoku(origin, nx, ny);
           break;
        } else if (r == 0) {
          origin[x][y] = i;
           int nx = (y == 8 ? x + 1 : x);
           int ny = (y == 8 ? 0 : y + 1);
          verifySudoku(origin, nx, ny);
        }
      }
      origin[x][y] = 0;
    } else {
       if (x == 8 && y == 8) {
        result = copySudoku(origin);
        isResolved = true;
         return;
      }
       int nx = (y == 8 ? x + 1 : x);
       int ny = (y == 8 ? 0 : y + 1);
      verifySudoku(origin, nx, ny);
    }
  }

   public boolean resolve() {
    verifySudoku(origin, 0, 0);
     return isResolved;
  }

   public static void main(String[] args) {
     int[][] sudoku = { { 0, 3, 7, 0, 0, 0, 0, 6, 0 }, { 6, 0, 9, 0, 0, 4, 8, 0, 0 }, { 8, 1, 0, 0, 6, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 5, 0, 0 }, { 1, 0, 0, 2, 4, 0, 6, 0, 9 },
        { 5, 0, 0, 6, 0, 0, 0, 4, 0 }, { 0, 0, 3, 0, 7, 0, 0, 0, 6 }, { 0, 0, 6, 1, 0, 9, 0, 2, 5 }, { 0, 0, 0, 0, 0, 6, 0, 0, 0 } };
    SudoKuRecursion sr = new SudoKuRecursion(sudoku);
    sr.resolve();
    sr.printResult();
  }
}