1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 const int N = 9;
7 const int Group[9][9] =
8 {
9 //便于找出是否在同一个9*9的里面出现过
10 0, 0, 0, 1, 1, 1, 2, 2, 2,
11 0, 0, 0, 1, 1, 1, 2, 2, 2,
12 0, 0, 0, 1, 1, 1, 2, 2, 2,
13 3, 3, 3, 4, 4, 4, 5, 5, 5,
14 3, 3, 3, 4, 4, 4, 5, 5, 5,
15 3, 3, 3, 4, 4, 4, 5, 5, 5,
16 6, 6, 6, 7, 7, 7, 8, 8, 8,
17 6, 6, 6, 7, 7, 7, 8, 8, 8,
18 6, 6, 6, 7, 7, 7, 8, 8, 8
19 };
20
21 int a[N][N];
22 int row[N][N], col[N][N], gr[N][N];//行 列 3*3矩阵
23
24 int judge()
25 {
26 int vis[N];
27
28 for(int i=0; i<N; i++)//行
29 {
30 for(int j=0; j<N; j++) vis[j] = 0;
31 for(int j=0; j<N; j++) vis[a[i][j]] = 1;
32 for(int j=0; j<N; j++) if(!vis[j]) return 0;
33 }
34
35 for(int i=0; i<N; i++)//列
36 {
37 for(int j=0; j<N; j++) vis[j] = 0;
38 for(int j=0; j<N; j++) vis[a[j][i]] = 1;
39 for(int j=0; j<N; j++) if(!vis[j]) return 0;
40 }
41
42 for(int i=0; i<N; i++)//3*3矩阵
43 {
44 for(int j=0; j<N; j++) vis[j] = 0;
45 for(int j=0; j<N; j++)
46 for(int k=0; k<N; k++)
47 if(Group[j][k] == i)
48 vis[a[j][k]] = 1;
49 for(int j=0; j<N; j++)
50 if(!vis[j])
51 return 0;
52 }
53 return 1;
54 }
55
56 void print()
57 {
58 //printf("One Possible Solution:\n");
59 for(int i=0; i<N; i++)
60 {
61 for(int j=0; j<N; j++)
62 printf("%d ", a[i][j] + 1);//因为输入时减去了1
63 printf("\n");
64 }
65 }
66
67 void dfs1(int x, int y)
68 {
69 if(x == N)//胜利条件
70 {
71 if(judge()) print();//进行判断当前所形成的9*9是否满足条件
72 return;
73 }
74
75 int next_x = x, next_y = y + 1;
76 if(next_y == N) next_x = x + 1, next_y = 0;//继续下一行
77
78 if(a[x][y] >= 0) dfs1(next_x, next_y);//如果当前位置搜索过了
79 else
80 {
81 for(int i=0; i<N; i++)
82 {
83 a[x][y] = i;//先赋值
84 dfs1(next_x, next_y);//继续搜索
85 }
86 }
87 }
88
89 void dfs2(int x, int y)
90 {
91 if(x == N)//胜利条件
92 {
93 print();
94 return;
95 }
96
97 int next_x = x, next_y = y + 1;
98 if(next_y == N) next_x = x + 1, next_y = 0;//进行下一行的搜索
99
100 if(a[x][y] >= 0) dfs2(next_x, next_y);//如果当前的数字被搜索过了
101 else
102 {
103 for(int i=0; i<N; i++)
104 {
105 a[x][y] = -1;//初始化
106
107 int okay = 1;
108 for(int j=0; j<N && okay; j++)
109 if(a[j][y]==i)//当前一列出现过该数字
110 okay = 0;//不满足,进行标记
111 for(int j=0; j<N && okay; j++)
112 if(a[x][j]==i)//当前一行出现过该数字
113 okay = 0;
114 for(int j=0; j<N && okay; j++)
115 for(int k=0; k<N && okay; k++)//该3*3矩阵中出现过该数字
116 if(Group[j][k]==Group[x][y] &&
117 a[j][k]==i) okay = 0;
118
119 if(okay)//如果搜索过后满足条件
120 {
121 a[x][y] = i;//记录下来
122 dfs2(next_x, next_y);//进行下一步的搜索
123 }
124 }
125
126 a[x][y] = -1;//回溯
127 }
128 }
129
130 void dfs3(int x, int y)
131 {
132 if(x == N)//胜利条件
133 {
134 print();
135 return;
136 }
137
138 int next_x = x, next_y = y + 1;//一行一行进行搜索
139 if(next_y == N) next_x = x + 1, next_y = 0;
140
141 if(a[x][y] >= 0) dfs3(next_x, next_y);//该行搜索完成,进行下一行的搜索
142 else
143 {
144 for(int i=0; i<N; i++)
145 if(!row[x][i] && !col[y][i] && !gr[Group[x][y]][i])
146 {
147 row[x][i] = col[y][i] = gr[Group[x][y]][i] = 1;
148 a[x][y] = i;//记录下数字
149 dfs3(next_x, next_y);
150 a[x][y] = -1;//回溯
151 row[x][i] = col[y][i] = gr[Group[x][y]][i] = 0;
152 }
153 }
154 }
155
156 int main()
157 {
158 for(int i=0; i<N; i++)
159 for(int j=0; j<N; j++)
160 scanf("%d", &a[i][j]), a[i][j]--;//因为是从0号开始的
161
162 /* 3种做法 */
163
164 //printf("Dfs Method1:\n");
165 //dfs1(0, 0);
166
167 //printf("Dfs Method2:\n");
168 //dfs2(0, 0);
169
170 //printf("Dfs Method3:\n");
171
172 for(int i=0; i<N; i++)//(将一开始就有的数字进行标记)
173 for(int j=0; j<N; j++)//双层循环
174 if(a[i][j] >= 0)//如果他是数字,那么相应的进行标记
175 row[i][a[i][j]] = 1,//该行该数字已经出现过
176 col[j][a[i][j]] = 1,//该列该数字已经出现过
177 gr[Group[i][j]][a[i][j]] = 1;
178 //3*3矩阵的分类,标记在当前的3*3矩阵中该数字已经出现过了
179
180 dfs3(0, 0);//从头开始进行搜索
181
182 return 0;
183 }