POJ_2676:数独问题-DFS暴力搜索

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Gods_magic/article/details/53788247

                                                                                                                          Sudoku
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 19230   Accepted: 9241   Special Judge

Description

Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task.

Input

The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.

Output

For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.

Sample Input

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107

Sample Output

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127
数独问题;注意DFS在回溯时要进行还原,注意标志位的运用(只要求输出一个结果),迭代从0到80比较慢,从80到0较快
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Test39_poj2676 {
	static int[][] Maze = new int[9][9];
	static int flsg = 0;// 标志位

	public static void main(String[] args) throws FileNotFoundException {
		Scanner in = new Scanner(new FileInputStream(
				"E:\\Test_Case\\Test39_poj2676.txt"));
		// Scanner in = new Scanner(System.in);
		int caseNum = in.nextInt();
		for (int i = 0; i < caseNum; i++) {
			for (int j = 0; j < 9; j++) {
				String rowNum = in.next();
				for (int m = 0; m < rowNum.length(); m++) {
					Maze[j][m] = Integer.parseInt(rowNum.substring(m, m + 1));
				}
			}
			flsg = 0;// 初始化标志位的值
			// 开始迭代,倒着迭代
			DFS(80);
		}
	}

	// 迭代体
	public static void DFS(int step) {
		int row = step / 9;// 点的横坐标
		int column = step % 9;// 点的纵坐标
		// 结束条件
		if (step == -1) {
			flsg = 1;// 将标志位置1
			// 输出结果
			for (int i = 0; i < 9; i++) {
				for (int j = 0; j < 9; j++) {
					System.out.print(Maze[i][j]);
				}
				System.out.println();
			}
			return;
		}
		if (Maze[row][column] == 0) {// 如果这个位置的值为0
			for (int temp = 1; temp < 10; temp++) {// 从1到9进行遍历
				// 判定行、列、分区是否有重复
				if (isSafe(row, column, temp)) {
					Maze[row][column] = temp;// 赋值
					DFS(step - 1);// 继续下一次迭代
					Maze[row][column] = 0;// 这个地方要进行还原!
					// 只要求输出一个结果,所以当标志位为1(已经输出一次)时,直接退出
					if (flsg == 1) {
						return;
					}
				}
			}
		} else {// 如果这个位置的值不为0,继续下个位置
			DFS(step - 1);
		}
	}

	// 判断在行、列、分区是否有重复
	public static boolean isSafe(int row, int column, int temp) {
		boolean isF = true;
		for (int i = 0; i < 9; i++) {
			// 1.行不能有重复
			if (Maze[row][i] == temp) {
				isF = false;
				return isF;
			}
			// 2.列不能有重复
			if (Maze[i][column] == temp) {
				isF = false;
				return isF;
			}
		}
		// 3.确定分区,分区内也不能有重复
		int[] tempX = partition(row);
		int[] tempY = partition(column);
		// 遍历此点所在的分区
		for (int i = tempX[0]; i <= tempX[1]; i++) {
			for (int j = tempY[0]; j <= tempY[1]; j++) {
				if (Maze[i][j] == temp) {
					isF = false;
					return isF;
				}
			}
		}
		return isF;
	}

	// 确定分区的起止坐标
	public static int[] partition(int ind) {
		int[] DX = new int[2];
		if (ind < 3) {
			DX[0] = 0;
			DX[1] = 2;
			return DX;
		} else if (ind < 6 && ind > 2) {
			DX[0] = 3;
			DX[1] = 5;
			return DX;
		} else {
			DX[0] = 6;
			DX[1] = 8;
			return DX;
		}
	}
}


猜你喜欢

转载自blog.csdn.net/Gods_magic/article/details/53788247