1 #include <cstdio>
2 #include <iostream>
3 #include <algorithm>
4 #include <cstring>
5 using namespace std;
6 const int N=20;
7
8 #define res register int
9 int map[N][N];
10 unsigned short t[N][N];
11 //table[i,j](二进制)表示(i,j)可以填的数,0可填,1不可填
12 int filled(0);
13
14 inline void my_fill(int x,int y,int a)//(x,y)填a
15 {
16 filled++;
17 map[x][y]=a;
18 t[x][y] |=1<<(a-1);
19 for(res i=0 ; i<16 ; i++)
20 t[x][i] |=1<<(a-1),
21 t[i][y] |=1<<(a-1);
22 int r=x/4*4,c=y/4*4;//(r,c)表示(x,y)所在的16宫格的左上角的格子,(从(0,0)开始)
23 for(res i=0 ; i<4 ; i++)
24 for(res j=0 ; j<4 ; j++) t[r+i][j+c] |=1<<(a-1);
25 }
26
27 //判断x中0的个数是否只有1个
28 int count_zero(unsigned short x)
29 {
30 int p(-1);
31 for(int i=0;x;i++)
32 {
33 if(x&1==0)
34 {
35 if(p!=-1) return -1;
36 p=i;
37 }
38 x>>=1;
39 }
40 return p;
41 }
42
43 //第x行,数字k+1,返回>0表示唯一可填的k+1的位置,-1表示有多个可以填的位置或已经填过,-2不能填
44 inline int col(int x,int k)
45 {
46 int p(-1);
47 for(res y=0 ; y<16 ; y++)
48 {
49 if(map[x][y]==k+1) return -1;//已经填过
50 if(map[x][y]>0) continue;
51 if((t[x][y]&(1<<k))==0)
52 {
53 if(p!=-1) return -1;//多次出现
54 p=y;
55 }
56 }
57 if(p!=-1) return p;
58 return -2;
59 }
60
61 //第y列,数字k
62 inline int row(int y,int k)
63 {
64 int p=-1;
65 for(res x=0 ; x<16 ; x++)
66 {
67 if(map[x][y]==k+1) return -1;
68 if(map[x][y]>0) continue;
69 if((t[x][y]&(1<<k))==0)
70 {
71 if(p!=-1) return -1;
72 p=x;
73 }
74 }
75 if(p!=-1) return p;
76 return -2;
77 }
78
79 inline void grid(int r,int c,int k,int &x,int &y)
80 //以(r,c)为左上角的16宫格,数字k+1,(x,y)为唯一可填坐标[
81 {
82 x=-2;
83 for(res i=0 ; i<4 ; i++)
84 for(res j=0 ; j<4 ; j++)
85 {
86 if(map[r+i][c+j]==k+1) {x=-1; return ;}
87 if(map[r+i][c+j]>0) continue;
88 if((t[r+i][c+j]&(1<<k))==0)
89 {
90 if(x!=-2) {x=-1; return ;}
91 x=i,y=j;
92 }
93 }
94 }
95
96 inline int count_1(unsigned short x) {
97 int tmp(0);
98 while(x) {
99 if(x&1) tmp++;
100 x>>=1;
101 }
102 return tmp;
103 }
104
105 bool search()
106 {
107 if(filled==256) return true;
108 //先看是否有能确定的格子
109 for(res x=0 ; x<16 ; x++)
110 for(res y=0 ; y<16 ; y++)
111 {
112 if(map[x][y]>0) continue;
113 int k=count_zero(t[x][y]);
114 if(k!=-1) my_fill(x,y,k+1);
115 }
116 for(res x=0 ; x<16 ; x++)
117 for(res k=0 ; k<16 ; k++)
118 {
119 int y=col(x,k);
120 if(y==-2) return false;
121 if(y!=-1) my_fill(x,y,k+1);
122 }
123 for(res y=0 ; y<16 ; y++)
124 for(res k=0 ; k<16 ; k++)
125 {
126 int x=row(y,k);
127 if(x==-2) return false;
128 if(x!=-1) my_fill(x,y,k+1);
129 }
130 for(res r=0 ; r<16 ; r+=4)
131 for(res c=0 ; c<16 ; c+=4)
132 for(res k=0 ; k<16 ; k++)
133 {
134 int x,y;
135 grid(r,c,k,x,y);
136 if(x==-2) return false;
137 if(x!=-1) my_fill(r+x,c+y,k+1);
138 }
139 if(filled==256) return true;
140 int t_filled(filled);
141 int t_map[N][N];
142 unsigned short t_t[N][N];
143 for(res i=0 ; i<16 ; i++)
144 for(res j=0 ; j<16 ; j++)
145 t_map[i][j]=map[i][j],
146 t_t[i][j]=t[i][j];
147 //找可能情况最少的格子来枚举
148 int mx,my,mn=16;
149 for(res i=0 ; i<16 ; i++)
150 for(res j=0 ; j<16 ; j++)
151 {
152 if(map[i][j]>0) continue;
153 int r=16-count_1(t[i][j]);
154 //未确定的
155 if(r<mn)
156 {
157 mn=r; mx=i; my=j;
158 }
159 }
160 for(res k=0 ; k<16 ; k++)
161 if((t[mx][my]&1<<k)==0)
162 {
163 my_fill(mx,my,k+1);
164 if(search()) return true;
165 filled=t_filled;
166 for(res i=0 ; i<16 ; i++)
167 for(res j=0 ; j<16 ; j++)
168 map[i][j]=t_map[i][j],
169 t[i][j]=t_t[i][j];
170 }
171 return false;
172 }
173
174 char ar[N];
175 int main()
176 {
177 while(1)
178 {
179 filled=0;
180 memset(map,0,sizeof(map)); memset(t,0,sizeof(t));
181 for(int i=0 ; i<16 ; i++)
182 {
183 if(scanf("%s",ar)==EOF) return 0;
184 for(int j=0 ; j<16 ; j++)
185 if(ar[j]!='-') my_fill(i,j,ar[j]-'A'+1);
186 }
187 search();
188 for(res i=0 ; i<16 ; i++)
189 {
190 for(res j=0 ; j<16 ; j++) printf("%c",map[i][j]+'A'-1);
191 puts("");
192 }
193 puts("");
194 }
195 return 0;
196 }