dfs练习题
import java.util.Scanner;
/**
* @author sjf
* @date 2020/3/3 15:04
*/
public class dfs数独游戏 {
static char[][] map = {{'0','6','1','0','3','0','0','2','0'},
{'0','5','0','0','0','8','1','0','7'},
{'0','0','0','0','0','7','0','3','4'},
{'0','0','9','0','0','6','0','7','8'},
{'0','0','3','2','0','9','5','0','0'},
{'5','7','0','3','0','0','9','0','0'},
{'1','9','0','7','0','0','0','0','0'},
{'8','0','2','4','0','0','0','6','0'},
{'0','4','0','0','1','0','2','5','0'}};/*new char[9][9]*/;
static int n=9 ; //棋盘大小
public static void main(String[] args) {
print();
System.out.println("==========================");
dfs(0,0);
}
public static void dfs(int x ,int y){
if(x==9){ //当x为9时,也就是遍历完整个数独游戏的时候
print();
System.exit(0); //直接返回第一步,这里不回溯
}
if(map[x][y] == '0') {
for (char j = '1'; j <= '9'; j++) {
if (check(x, y, j)) {
map[x][y] = j;
dfs(x+(y+1)/9, (y+1)%9); //巧妙方法
}
}
/* 这里当一个递归回退时,先做的事情是继续执行循环,添加合适的数
往数独里面,当for循环终止也就是意味着 没有数字可以填进去,说明前
面有错误,这时才应该回溯*/
map[x][y] = '0'; //回溯
}
else
dfs(x+(y+1)/9, (y+1)%9);
}
//小技巧
//检查是否满足数独规则
public static boolean check(int x ,int y , char num){
//检查同行同列
for (int i = 0; i <n ; i++) {
if(map[x][i]==num) return false;
if(map[i][y]==num) return false;
}
//检查小九宫格
for (int i = (x/3)*3; i <(x/3+1)*3 ; i++) {
for (int j = (y/3)*3; j <(y/3+1)*3 ; j++) {
if(map[i][j]==num)
return false;
}
}
return true;
}
//打印数独
public static void print(){
for (int i = 0; i <n; i++) {
System.out.println(new String(map[i]));
}
}
}
数独这个例子在每次递归调用都要在内部进行操作,对dfs的运行原理理解更深
public static void dfs(int x ,int y){
if(x==9){ //当x为9时,也就是遍历完整个数独游戏的时候
print();
System.exit(0); //直接返回第一步,这里不回溯
}
if(map[x][y] == '0') {
for (char j = '1'; j <= '9'; j++) {
if (check(x, y, j)) {
map[x][y] = j;
dfs(x+(y+1)/9, (y+1)%9); //巧妙方法
}
}
/* 这里当一个递归回退时,先做的事情是继续执行循环,添加合适的数
往数独里面,当for循环终止也就是意味着 没有数字可以填进去,说明前
面有错误,这时才应该回溯*/
map[x][y] = '0'; //回溯
}
else
dfs(x+(y+1)/9, (y+1)%9);
}