思路:
将每一个 ? 位置存储起来,每一个位置从1到9枚举,符合条件就存上。具体思路看代码
注意数据的读入,方式不对会导致TLE
import java.util.*;
public class Main {
static class node
{
int x,y;
node(){};
node(int x,int y)
{
this.x = x;
this.y = y;
}
}
static node[]p = new node[81];
static int[][] map = new int[9][9];
static int num; //有多少个位置需要填数
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
int t = 0;
String s;
while(cin.hasNext())
{
num = 0;
for(int i=0;i<9;i++)
{
//s = cin.nextLine();
for(int j=0;j<9;j++)
{
s = cin.next(); //注意输入格式 一次只读取一个字符 如果一次读入一行会导致TLE
char[] a = s.toCharArray();
if(a[0]>='1' && a[0]<='9')
map[i][j] = a[0]-'0';
else if(a[0]=='?')
{
map[i][j] = 0;
p[num] = new node(i,j);
num++;
}
}
}
if(t++ > 0)
System.out.println();
dfs(0);
}
}
public static void dfs(int k)
{
if(k==num) //所有位置都填满 输出
{
for(int i=0;i<9;i++)
{
for(int j=0;j<8;j++)
System.out.print(map[i][j]+" ");
System.out.println(map[i][8]);
}
return ;
}
for(int i=1;i<=9;i++)
{
if(check(k,i)==1) //判断能否填数
{
map[p[k].x][p[k].y] = i; //填数
dfs(k+1); //搜索下一个位置的填法
map[p[k].x][p[k].y] = 0; //还原
}
}
return ;
}
public static int check(int n,int k)
{
for(int i=0;i<9;i++) //判断行和列是否有与 k 重复的值
{
if(map[p[n].x][i]==k || map[i][p[n].y]==k)
return 0;
}
int x = p[n].x/3*3;
int y = p[n].y/3*3;
//判断所在的 3*3 子矩阵中是否有与 k 重复的值
for(int i=x;i<x+3;i++)
{
for(int j=y;j<y+3;j++)
{
if(map[i][j]==k)
return 0;
}
}
return 1;
}
}