输入一个
的不完整数独矩阵,矩阵中的数字为
。其中,
表示该位置的数字尚未填入,
表示该位置的数字已经填入。
输出一个
的完整数独矩阵。
0 9 2 4 8 1 7 6 3 4 1 3 7 6 2 9 8 5 8 6 7 3 5 9 4 1 2 6 2 4 1 9 5 3 7 8 7 5 9 8 4 3 1 2 6 1 3 8 6 2 7 5 9 4 2 7 1 5 3 8 6 4 9 3 8 6 9 1 4 2 5 7 0 4 5 2 7 6 8 3 1
5 9 2 4 8 1 7 6 3 4 1 3 7 6 2 9 8 5 8 6 7 3 5 9 4 1 2 6 2 4 1 9 5 3 7 8 7 5 9 8 4 3 1 2 6 1 3 8 6 2 7 5 9 4 2 7 1 5 3 8 6 4 9 3 8 6 9 1 4 2 5 7 9 4 5 2 7 6 8 3 1
在这个样例中,输入的数独如下图一所示,输出的是数独的唯一解,如下图二所示。
import java.util.*;
public class Main {
public static int[][] sudo = new int[9][9];//创建数组
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
sudo[i][j]=sc.nextInt();//创建数独
}
}
if(backTracking(sudo)){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(j==8){
//最后一位数需要换行输出
System.out.println(sudo[i][j]);
}else{
System.out.print(sudo[i][j]+" ");
}
}
}
}
}
}
public static boolean backTracking(int[][] sudo){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){//遍历数组
if(sudo[i][j]!=0){//如果不需要填数字直接continue
continue;
}
for(int k=1;k<=9;k++){//循环填数字
if(isValid(i,j,k,sudo)){//判断填入数字是否符合要求
sudo[i][j]=k;//填数字
if(backTracking(sudo)){//递归
return true;
}
sudo[i][j]=0;//回溯
}
}
return false;//如果没有符合要求的数字返回false
}
}
return true;
}
public static boolean isValid(int row,int col,int k,int[][] sudo){
for(int i=0;i<9;i++){//检查行
if(sudo[row][i]==k){
return false;
}
}
for(int i=0;i<9;i++){//检查列
if(sudo[i][col]==k){
return false;
}
}
int startRow = (row/3)*3;
int endCol = (col/3)*3;
for(int i=startRow;i<startRow+3;i++){//检查九宫格
for(int j=endCol;j<endCol+3;j++){
if(sudo[i][j]==k){
return false;
}
}
}
return true;
}
}
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.IntStream;
public class Main {
private static int BOARD_SIZE = 9;
private static int SUBSECTION_SIZE = 3;
private static int NO_VALUE = 0;
private static int MIN_VALUE = 1;
private static int MAX_VALUE = 9;
private static int BOARD_START_INDEX = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[][] bc = new int[9][9];
while (sc.hasNextLine()) {
for (int i = 0; i < 9; i++) {
String str = sc.nextLine();
String[] ss = str.split(" ");
for (int j = 0; j < 9; j++) {
bc[i][j] = Integer.parseInt(ss[j]);
}
}
solve(bc);
printBoard(bc);
}
}
private static boolean isValid(int[][] board, int row, int column) {
return (rowConstraint(board, row) && columnConstraint(board, column)
&& subsectionConstraint(board, row, column));
}
private static boolean rowConstraint(int[][] board, int row) {
boolean[] constraint = new boolean[BOARD_SIZE];
return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
.allMatch(column -> checkConstraint(board, row, constraint, column));
}
private static boolean columnConstraint(int[][] board, int column) {
boolean[] constraint = new boolean[BOARD_SIZE];
return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
.allMatch(row -> checkConstraint(board, row, constraint, column));
}
private static boolean subsectionConstraint(int[][] board, int row, int column) {
boolean[] constraint = new boolean[BOARD_SIZE];
int subsectionRowStart = (row / SUBSECTION_SIZE) * SUBSECTION_SIZE;
int subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE;
int subsectionColumnStart = (column / SUBSECTION_SIZE) * SUBSECTION_SIZE;
int subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE;
for (int r = subsectionRowStart; r < subsectionRowEnd; r++) {
for (int c = subsectionColumnStart; c < subsectionColumnEnd; c++) {
if (!checkConstraint(board, r, constraint, c))
return false;
}
}
return true;
}
private static boolean checkConstraint(int[][] board, int row, boolean[] constraint, int column) {
if (board[row][column] != NO_VALUE) {
if (!constraint[board[row][column] - 1]) {
constraint[board[row][column] - 1] = true;
} else {
return false;
}
}
return true;
}
private static void printBoard(int[][] board) {
for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) {
System.out.println(Arrays.toString(board[row]).replaceAll("[,\\[\\]]", ""));
}
}
private static boolean solve(int[][] board) {
for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) {
for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) {
if (board[row][column] == NO_VALUE) {
for (int k = MIN_VALUE; k <= MAX_VALUE; k++) {
board[row][column] = k;
if (isValid(board, row, column) && solve(board)) {
return true;
}
board[row][column] = NO_VALUE;
}
return false;
}
}
}
return true;
}
}
case通过率为83.33%代码如下:
#include <iostream>
using namespace std;
bool sign = false;
int num[9][9];
void Output()
{
for (int i = 0; i < 9; i++){
for (int j = 0; j < 8; j++)
cout << num[i][j] << " ";
cout << num[i][8];
cout << endl;
}
}
/* 判断key填入n格时是否满足条件,n代表第几个格子 */
bool Check(int n, int key)
{
/* 判断n所在横列是否合法 */
for (int i = 0; i < 9; i++){
/* j为n竖坐标 */
int j = n / 9;
if (num[j][i] == key)
return false;
}
/* 判断n所在竖列是否合法 */
for (int i = 0; i < 9; i++){
/* j为n横坐标 */
int j = n % 9;
if (num[i][j] == key)
return false;
}
int y = n / 9 / 3 * 3;
int x = n % 9 / 3 * 3;
/* 判断n所在的小九宫格是否合法 */
for (int i = y; i < y + 3; i++)
for (int j = x; j < x + 3; j++)
if (num[i][j] == key)
return false;
return true;
}
/* 深搜 */
int DFS(int n)
{
/* 所有的都符合,退出搜索,n代表格子数,共81个格子,0~80 */
if (n > 80){
sign = true;
return 0;
}
if (num[n / 9][n % 9] != 0)
DFS(n + 1);
else{
/* 否则对当前位一次填入1~9进行测试 */
for (int i = 1; i <= 9; i++){
if (Check(n, i)){
num[n / 9][n % 9] = i;
/* 继续搜索,后续位也填1~9测试,直到最后一位,通过的话置true */
DFS(n + 1);
/* 返回时如果构造成功,则直接退出 */
if (sign)
return 0;
/* 如果构造不成功,还原当前位 */
num[n/9][n%9] = 0;
}
}
}
return 0;
}
int main()
{
for (int i = 0; i < 9; i++){
for (int j = 0; j < 9; j++)
cin >> num[i][j];
}
DFS(0); //从第0格开始填
Output();
}
#-*- coding: utf8 -*-
def check(matrix,row,col,value):
"""
检测在(row,col)放value是否合适
1.每行含1-9,不含重复值value
2.每列含1-9,不含重复值value
3.3*3区块含1-9,不含重复值value
"""
#检测每行
for j in range(9):
if matrix[row][j]==value:
return False
#检测每列
for i in range(9):
if matrix[i][col]==value:
return False
#检测元素所在3*3区域
area_row=(row/3)*3
area_col=(col/3)*3
for i in range(area_row,area_row+3):
for j in range(area_col,area_col+3):
if matrix[i][j]==value:
return False
return True
def solveSudoku(matrix,count=0):
"""
遍历每一个未填元素,遍历1-9替换为合适的数字
"""
if (count==81):#递归出口
return True
row=count/9#行标
col=count%9#列标
if (matrix[row][col]!=0):#已填充
return solveSudoku(matrix,count=count+1)
else:#未填充
for i in range(1,10):
if check(matrix,row,col,i):#找到可能的填充数
matrix[row][col]=i
if solveSudoku(matrix,count=count+1):#是否可完成
return True#可完成
#不可完成
matrix[row][col]=0#回溯
return False#不可完成
matrix=[]
for i in range(9):
matrix.append(map(int,raw_input().split(' ')))
solveSudoku(matrix)
for i in range(9):
print ' '.join(map(str,matrix[i]))
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[][] matrix = new int[9][9];
while (sc.hasNext()) {
for (int i = 0; i < 9; i ++) {
for (int j = 0; j < 9; j ++) {
matrix[i][j] = sc.nextInt();
}
}
sudoku(matrix, 0, 0);
for (int i = 0; i < 9; i ++) {
for (int j = 0; j < 9; j ++) {
if(j == 8) System.out.println(matrix[i][j]);
else System.out.print(matrix[i][j] + " ");
}
}
}
}
public static boolean sudoku(int[][] matrix, int i, int j) {
if(i > 8) return true;
if(matrix[i][j] != 0) {
if(j < 8 && sudoku(matrix, i, j + 1)) return true; // 未到行位,求解同行下一个
else if(j >= 8 && sudoku(matrix, i + 1, 0)) return true; // 已到行位,求解下一行第一个
} else {
for (int num = 1; num <= 9; num ++) {
if(check(matrix, i, j, num)) {
matrix[i][j] = num;
if(j < 8 && sudoku(matrix, i, j + 1)) return true;
else if(j >= 8 && sudoku(matrix, i + 1, 0)) return true;
matrix[i][j] = 0; // 回溯
}
}
}
return false;
}
// 检查行、列、3*3格
public static boolean check(int[][] matrix, int i, int j, int num) {
if(check_row(matrix, i, j, num) && check_col(matrix, i, j, num) && check_3_by_3(matrix, i, j, num)) return true;
return false;
}
// 检查所在行
public static boolean check_row(int[][] matrix, int i, int j, int num) {
for (int k = 0; k < 9; k ++) {
if(matrix[i][k] == num) return false;
}
return true;
}
// 检查所在列
public static boolean check_col(int[][] matrix, int i, int j, int num) {
for (int k = 0; k < 9; k ++) {
if(matrix[k][j] == num) return false;
}
return true;
}
// 检查所在3*3格
public static boolean check_3_by_3(int[][] matrix, int i, int j, int num) {
int row_from = i / 3 * 3;
int row_to = row_from + 2;
int col_from = j / 3 * 3;
int col_to = col_from + 2;
for (int x = row_from; x <= row_to; x ++) {
for (int y = col_from; y <= col_to; y ++) {
if(matrix[x][y] == num) return false;
}
}
return true;
}
}
def value(x, y):
i, j = x // 3, y // 3
grid = [m[i * 3 + r][j * 3 + c] for r in range(3) for c in range(3)]
row_val = m[x]
col_val = list(zip(*m))[y]
return {1, 2, 3, 4, 5, 6, 7, 8, 9} - set(grid) - set(row_val) - set(col_val)
def sudoku(pos):
if not pos: # 填完了
res.append([' '.join(map(str, i)) for i in m])
else:
x, y = pos[0]
val = value(x, y)
if val:
for v in val:
m[x][y] = v
sudoku(pos[1:])
m[x][y] = 0 # 回溯
m = [list(map(int, input().split())) for i in range(9)]
pos = [(x, y) for y in range(9) for x in range(9) if not m[x][y]]
res = []
sudoku(pos)
print('\n'.join(res[0])) import java.util.Scanner;
/**
* dfs解数独
* 从左往右,从上往下遍历每个格子
* 在空格处 循环1-9,检查能不能放,能放->放入,继续递归。不能放->回溯到上一个空格
* 当最后一行遍历完了,说明格子都填满了,直接结束。
*/
public class Main {
//定义数独数组,9行9列
public static int[][] arr = new int[9][9];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
//初始化数独数组
for (int i = 0;i < 9;i++){
for (int j = 0; j < 9;j++){
arr[i][j] = sc.nextInt();
}
}
//调用dfs方法
dfs(0,0);
//打印结果
for (int i = 0;i < 9;i++){
for (int j = 0; j < 9;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
/**
* dfs填数独
* @param x 当前的行
* @param y 当前的列
* @return
*/
public static boolean dfs(int x,int y){
//x的范围是0-8,如果x到9,说明数组已经全填完了,直接结束,返回true
if (x == 9){
return true;
}
//y的范围是0-8,如果到9,说明当前行已经遍历完所有列了,跳到下一行
if (y == 9){
return dfs(x+1,0);
}
//当前格子已经填了数字了,跳到下一个格子
if (arr[x][y] != 0){
return dfs(x,y+1);
}
//走到这一步说明当前这个格子是空的,还要判断一下是否能填数字
//循环1-9
for (int i = 1;i <= 9;i++){
//当前格子能填数字i
if (check(x,y,i)){
//填上
arr[x][y] = i;
//继续递归,如果能成功,返回true
if (dfs(x,y+1)){
return true;
}
//如果走到这一步,说明后面的某个格子填入失败了,回溯到这一步,把当前格子改回空格,继续循环
arr[x][y] = 0;
}
}
//如果循环完了没有数字能填入,结束当前dfs,返回false
return false;
}
/**
* 检查当前这个格子能不能填数字num
* @param x 当前行
* @param y 当前列
* @param num 准备填入的数字
* @return
*/
public static boolean check(int x ,int y , int num){
//循环遍历,拿传入的数字与每行,每列比较
for (int i = 0;i < 9 ;i++){
//与当前行其他数字比较
if (arr[x][i] == num){
return false;
}
//与当前列其他数字比较
if (arr[i][y] == num){
return false;
}
}
//循环遍历,那传入的数字与每个小九宫格里的数字比较
for (int i = (x/3)*3;i < (x/3)*3+3 ; i++){
for (int j = (y/3)*3; j < (y/3)*3+3;j++){
if (arr[i][j] == num){
return false;
}
}
}
return true;
}
}
import java.util.*;
public class Main {
public static void main(String[] args) {
int[][] board = new int[9][9];
Scanner in = new Scanner(System.in);
for (int i = 0; i < board[0].length; i++)
for (int j = 0; j < board.length; j++)
board[i][j] = in.nextInt();
in.close();
solveSudoku(board);
for (int i = 0; i < board[0].length; i++) {
for (int j = 0; j < board.length - 1; j++)
System.out.print(board[i][j] + " ");
System.out.println(board[i][board.length - 1]);
}
}
static int solveSudoku(int[][] board) {
int depth = 0;
for (int i[] : board)
for (int j : i)
if (j == 0)
depth++;
return dfs(board, depth);
}
static int dfs(int[][] board, int depth) {
if (depth == 0)
return 0;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == 0) {
for (int k = 1; k <= 10; k++) {
if (k == 10)
return depth;
board[i][j] = k;
if (!isValid(board, i, j))
board[i][j] = 0;
else {
depth--;
depth = dfs(board, depth);
if (depth == 0)
return depth;
depth++;
board[i][j] = 0;
}
}
}
}
}
return depth;
}
static boolean isValid(int[][] board, int row, int col) {
boolean[] check = new boolean[10];
for (int i = 0; i < check.length; i++)
check[i] = true;
for (int i = 0; i < board[0].length; i++) {
if (check[board[row][i]])
check[board[row][i]] = false;
else if (board[row][i] != 0)
return false;
}
for (int i = 0; i < check.length; i++)
check[i] = true;
for (int i = 0; i < board.length; i++) {
if (check[board[i][col]])
check[board[i][col]] = false;
else if (board[i][col] != 0)
return false;
}
for (int i = 0; i < check.length; i++)
check[i] = true;
int rowTemp = (row / 3) * 3;
int colTemp = (col / 3) * 3;
for (int k = 0; k < 9; k++) {
row = rowTemp + k / 3;
col = colTemp + k % 3;
if (check[board[row][col]])
check[board[row][col]] = false;
else if (board[row][col] != 0)
return false;
}
return true;
}
}
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
// 记录每行 每列 每个方格该位置的元素是否出现
private static boolean[][] row;
private static boolean[][] col;
private static boolean[][][] board;
private static int[][] matrix = new int[9][9];
private static boolean flag = false;
// 空缺列表
private static List<int[]> list;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
matrix[i][j] = in.nextInt();
}
}
row = new boolean[9][10];
col = new boolean[9][10];
board = new boolean[3][3][10];
list = new ArrayList<>();
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(matrix[i][j] == 0){
list.add(new int[]{i,j});
continue;
}
// 记录该元素已经在该行 该列 该单元格出现
row[i][matrix[i][j]] = col[j][matrix[i][j]] = board[i/3][j/3][matrix[i][j]] = true;
}
}
dfs(0);
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
System.out.print(matrix[i][j]);
if(j < 8) System.out.print(" ");
}
System.out.println();
}
}
}
// 回溯
public static void dfs(int cnt){
if(cnt == list.size()){
flag = true;
return ;
}
int[] cur = list.get(cnt);
int i = cur[0], j = cur[1];
for(int digit=1;digit<=9 && !flag;digit++){ // 枚举(i,j)填写的数字
if(!row[i][digit] && !col[j][digit] && !board[i/3][j/3][digit]){
row[i][digit] = col[j][digit] = board[i/3][j/3][digit] = true;
// 将数组中该位置的元素改为digit
matrix[i][j] = digit;
dfs(cnt+1);
//matrix[i][j] = 0;
row[i][digit] = col[j][digit] = board[i/3][j/3][digit] = false;
}
}
}
} #include <iostream>
#include<vector>
using namespace std;
class Sudoku{
private:
vector<vector<int>> sudoku;
public:
Sudoku()
{
sudoku.resize(9, vector<int>(9));
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
cin >> sudoku[i][j];
}
};
bool sudokuCheck(int i, int j, int n)
{
for(int p = 0; p < 9; ++p)
{
if (this->sudoku[i][p] == n)
return false;
if (this->sudoku[p][j] == n)
return false;
}
int ii = (int)(i / 3) * 3;
int jj = (int)(j / 3) * 3;
for(int p = 0; p < 3; ++p)
{
for(int q = 0; q < 3; ++q)
{
if (this->sudoku[ii + p][jj + q] == n)
return false;
}
}
return true;
}
bool sudokuCkeckDFS()
{
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
{
if(this->sudoku[i][j] == 0)
return false;
}
}
return true;
}
void sudokuDFS(int i, int j)
{
if(j >= 9)
{
j-=9;
i++;
}
if(i >= 9)
return;
if(this->sudoku[i][j] != 0)
{
sudokuDFS(i, j + 1);
}
else{
for(int num = 1; num <= 9; ++num)
{
if(sudokuCheck(i, j, num))
{
this->sudoku[i][j] = num;
sudokuDFS(i, j + 1);
if(sudokuCkeckDFS())
return;
this->sudoku[i][j] = 0;
}
}
}
}
void sudokuPrint()
{
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
cout<<sudoku[i][j] <<" ";
cout << endl;
}
}
};
int main()
{
Sudoku sudoku;
sudoku.sudokuDFS(0, 0);
sudoku.sudokuPrint();
return 0;
} import java.util.Scanner;
public class Main {
static boolean[][] rowBit = new boolean[9][9];
static boolean[][] colBit = new boolean[9][9];
static boolean[][] boxBit = new boolean[9][9];
public static void main(String args[]) {
int[][] question = new int[9][9];
Scanner scan = new Scanner(System.in);
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
int t = scan.nextInt();
question[row][col] = t;
if (t == 0)
continue;
setBit(row, col, t, true);
}
}
if (!solveSudoku(question, 0, 0))
System.out.println("无解");
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
System.out.print(question[row][col]+" ");
}
System.out.println();
}
}
public static boolean solveSudoku(int[][] q, int i, int j) {
for (; i < 9; i++) {
for (j = 0;j < 9; j++) {
// 找到空位
if (q[i][j] == 0) {
// 找一个可以填的数填入,递归
for (int test = 1; test < 10; test++) {
if (!rowBit[i][test-1] && !colBit[j][test-1] && !boxBit[getBox(i, j)][test-1]) {
q[i][j] = test;
setBit(i, j, test, true);
if (solveSudoku(q, i, j))
return true;
q[i][j] = 0;
setBit(i, j, test, false);
}
// 没有任何数可以填入
if (test == 9)
return false;
}
}
}
}
return true;
}
public static int getBox(int row, int col) {
return (row / 3) * 3 + col / 3;
}
public static void setBit(int i, int j, int test, boolean f) {
rowBit[i][test-1] = f;
colBit[j][test-1] = f;
boxBit[getBox(i, j)][test-1] = f;
}
} // 回溯,验证数的合法性的地方想了一下(
// 思路大概就是如下
#include <iostream>
#include <vector>
using namespace std;
bool isValid(vector<vector<int>>& arr, int i, int j, int num) {
for (int k = 0; k < 9; k++) {
if (arr[k][j] == num) // 列中重复
return false;
if (arr[i][k] == num) // 行中重复
return false;
if (arr[(i / 3) * 3 + k / 3][(j / 3) * 3 + k % 3] ==
num) //3*3方格内是否有重复
return false;
}
return true;
}
// 返回bool值,一找到可行解就return,省时间
bool backtrack(vector<vector<int>>& arr, int i, int j) {
if (i == 9) // base case,碰到直接返回
return true;
if (j == 9) // 这一行穷举完了就换下一行
return backtrack(arr, i + 1, 0);
if (arr[i][j] != 0) // 这格已经有数字了的话就跳过
return backtrack(arr, i, j + 1);
// 对每个格子,可以选择1~9
for (int k = 1; k <= 9; k++) {
// 先判断当前的数字能否放到格子里, 剪枝
if (!isValid(arr, i, j, k))
continue;
// 做选择
arr[i][j] = k;
// 继续穷举右边一个
if (backtrack(arr, i, j + 1))
return true;
//撤销选择
arr[i][j] = 0;
}
return false;
}
int main() {
vector<vector<int>> arr(9, vector(9, 0));
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
cin >> arr[i][j];
backtrack(arr, 0, 0);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
cout << arr[i][j] << " ";
cout << endl;
}
} a = []
def check(row, col, v):#传入位置和这个元素
for k in range(9):#判断,如果在这一行或者这一列里面以及有元素等于v了,就返回false
if a[row][k] == v&nbs***bsp;a[k][col] == v: return False
t = row//3#把9×9的转变为9个3×三的小矩阵
q = col//3
for k in range(t*3,t*3+3):#判断这个小矩阵,看这个小矩阵里面是否有元素等于这个数,如果有,就返回false!为什么判断这个呢??哦,题目要求了,这个小的矩形也不能重复的
for p in range(q*3,q*3+3):
if a[k][p] == v: return False
return True
def f(num):#不断的判断,某个位置是否能够填这个数。
global a
if num > 80: return True#大于80,说明全部扫完了。
row = num // 9#行数,行数和列数是变化的。明显列数变化的比行快一些
col = num % 9#列数
if a[row][col] != 0: return f(num+1)#不等于0,说明这个地方有数,占住了位子
else:#否则,就是等于0,需要考虑填什么数合适
for i in range(1,10):
if check(row,col,i): #检查,这个位置填i可以吗,如果可以则填
a[row][col] = i
if f(num+1): return True
else: a[row][col] = 0
return False
while True:
try:
for i in range(9):
b = list(map(int,input().split()))
a.append(b)
f(0)
for i in range(9):
print(' '.join(map(str,a[i])))
except:
break 批注了一下,便于理解这一段代码,排第一的python解法#include <iostream>
using namespace std;
int flag = 0;
int a[9][9];
//思想
//遍历矩阵,判断数字是否为0
//若为0,判断1-9哪个数字合适(因此需要判断,0所在行,所在列,所在9宫格是否有重复)
//若没有重复,则复制,继续循环到第81个数字,那么说明数独填数成功
bool isok(int n,int k)
{
int x = n/9;
int y = n%9;
for(int i=0;i<9;i++)
{
if(a[x][i] == k) return false;
}
for(int i=0;i<9;i++)
{
if(a[i][y] == k) return false;
}
x = x/3 *3;
y = y/3 *3;
for(int i = x;i<x+3;i++)
{
for(int j = y;j<y+3;j++)
{
if(a[i][y] == k) return false;
}
}
return true;
}
void dfs(int n)
{
if(n > 80)
{
flag =1;
return ;
}
int x = n/9;
int y = n%9;
if(a[x][y] != 0)
{
dfs(n+1);
}
else
{
for(int i = 1;i<=9;i++)
{
if(isok(n,i))
{
a[x][y] = i;
dfs(n+1);
if(flag == 1)
return;
else
a[x][y] = 0;
}
}
}
}
int main()
{
for(int i = 0;i<9;i++)
for(int j = 0;j<9;j++)
cin>>a[i][j];
dfs(0);
for(int i = 0;i<9;i++)
{
for(int j = 0;j<9;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return 0;
} def check(sod,loc,value):
x, y = loc//9,loc%9
row = sod[x]
column = list(b[y] for b in sod)
x1,y1 = (x//3)*3,(y//3)*3
L1,L2,L3 = sod[x1][y1:y1+3],sod[x1+1][y1:y1+3],sod[x1+2][y1:y1+3]
matrix = L1+L2+L3
allnum = row+column+matrix+[0]
if value in allnum:
return False
else:
return True
def solver(sodoku:list):
total = []
def search(sodo:list,nowloc=0):
if nowloc == 81:
for i in sodo:
print(' '.join(list(map(str,i))))
return True
x, y = nowloc//9,nowloc%9
if sodo[x][y] == 0:
for i in range(1,10,1):
if check(sodo,nowloc,i):
sodo[x][y] = i
if search(sodo,nowloc+1):
return True
else:
sodo[x][y] = 0
return False
else:
search(sodo,nowloc+1)
return False
search(sodoku,0)
return total
for i in range(1):
try:
mylist = []
for i in range(9):
mylist.append(list(map(int,input().split())))
solver(mylist)
except:
break
题目不完整,缺少粗线框的限制
import java.util.*;
class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int[][] arr = new int[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
arr[i][j] = scanner.nextInt();
}
}
if(!find(arr))System.out.println("no solution");
else {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
scanner.close();
}
public static boolean find(int[][] arr) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if(arr[i][j]==0){
for (int j2 = 0; j2 < 10; j2++) {
if(ok(arr,i,j,j2)) return true;
}
return false;
}
}
}
return true;
}
public static boolean ok(int[][] arr,int a,int b,int num){
for (int i = 0; i < 9; i++) {
if(arr[a][i]==num)return false;
}
for (int i = 0; i < 9; i++) {
if(arr[i][b]==num)return false;
}
for (int i = a/3*3; i < a/3*3+3; i++) {
for (int j = b/3*3; j < b/3*3+3; j++) {
if(arr[i][j]==num)return false;
}
}
arr[a][b]=num;
if(!find(arr)){
arr[a][b]=0;
return false;
}
return true;
}
} AC代码//回溯算法求解数独
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define WIDE 9
int Sudo[WIDE][WIDE] = { 0 };
int Flag[3][WIDE][WIDE] = { 0 };
//标记某数的占用情况
void updateFlag(int x, int y, int flag){
if ((x < 0) || (x > 8)){
return;
}
if ((y < 0) || (y > 8)){
return;
}
int box = (x / 3) * 3 + y / 3;
Flag[0][x][Sudo[x][y] - 1] = flag;
Flag[1][y][Sudo[x][y] - 1] = flag;
Flag[2][box][Sudo[x][y] - 1] = flag;
return;
}
//数独数据输入
int initSuDoKu(){
//输入数独数据
for (int i = 0; i<WIDE; i++){
for (int j = 0; j<WIDE; j++){
if (scanf("%d", Sudo[i] + j) == -1){
return -1;
}
if (Sudo[i][j]){
updateFlag(i, j, 1);
}
}
}
return 0;
}
//输出数独结果
void printSuDoKu(){
//输出
for (int i = 0; i<WIDE; i++){
for (int j = 0; j<WIDE; j++){
printf("%d ", Sudo[i][j]);
if (j >= 8){
printf("\n");
}
}
}
}
//获取某坐标的某可选值
int getValue(int x, int y,int start){
int box = (x / 3) * 3 + y / 3;
for (int i = start; i <= 9; i++){
if (Flag[0][x][i - 1]){
continue;
}
if (Flag[1][y][i - 1]){
continue;
}
if (Flag[2][box][i - 1]){
continue;
}
return i;
}
return 0;
}
//回溯算法求解数独
void trackBack(int x, int y){
//调整坐标
if (y == 9){
x++;
y = 0;
}
//获取需要填写的坐标
while ((x <= 8) && Sudo[x][y]){
y++;
if (y == 9){
x++;
y = 0;
}
}
//检测是否解数独成功
if (x > 8){
printSuDoKu();
//终止程序,只需要求一组解
exit(0);
}
//尝试填写值
while ((Sudo[x][y] = getValue(x, y,Sudo[x][y] + 1)) != 0){
//标记占用
updateFlag(x, y, 1);
//继续下移坐标
trackBack(x, y + 1);
//回溯
updateFlag(x, y, 0);
}
return;
}
int main(){
while (initSuDoKu() != -1){
trackBack(0, 0);
}
} /*假如九宫格如下:
0 9 5|0 2 0|0 6 0
0 0 7|1 0 3|9 0 2
6 0 0|0 0 5|3 0 4
-----------------
0 4 0|0 1 0|6 0 7
5 0 0|2 0 7|0 0 9
7 0 3|0 9 0|0 2 0
-----------------
0 0 9|8 0 0|0 0 6
8 0 6|3 0 2|1 0 5
0 5 0|0 7 0|2 8 3
中间的格子012 345 678 除以3是0 1 2,*3之后变为 0 3 6 正好对应每个粗线框的范围 (加3之后)
每一个虚线宫数字都含有1-9
这就是其中一条规则,处理这个规则的方法很巧妙
*/
#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int a[10][10];
bool flag=false;
bool check(int n,int p)
{
for(int i=0; i<9; i++)
{
if(a[n/9][i]==p)
return false;
}
for(int i=0; i<9; i++)
{
if(a[i][n%9]==p){
return false;
}
}
int x=n/9/3*3;
int y=n%9/3*3;
for(int i=x; i<x+3; i++)
for(int j=y; j<y+3; j++)
if(a[i][j] == p)
return false;
return true;
}
int dfs(int n)
{
if(n>80)
{
flag=true;
return 0;
}
int x=n/9;
int y=n%9;
if(a[x][y]!=0)
dfs(n+1);
else
{
for(int i=1; i<=9; i++)
{
if(check(n,i))
{
a[x][y]=i;
dfs(n+1);
if(flag)
return 0;
a[x][y]=0;
}
}
}
return 0;
}
int main()
{
// a[10][10]= {0};
// flag=false;
for(int i=0; i<9; i++)
for(int j=0; j<9; j++)
{
cin>>a[i][j];
}
dfs(0);
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
if(j<=7)
cout<<a[i][j]<<" ";
else
cout<<a[i][j];
}
cout<<endl;
}
return 0;
}