精确覆盖问题,用dancing links求解。
打常量表比较麻烦。
const int f[60][12]={
0,3,0,0,0,1,1,0,0,0,0,0,
0,3,0,0,0,1,1,1,0,0,0,0,
0,3,0,0,1,0,1,1,0,0,0,0,
0,3,0,1,1,0,1,1,0,0,0,0,
1,4,0,0,0,1,0,2,0,3,0,0,
1,4,0,0,1,0,2,0,3,0,0,0,
2,4,0,0,0,1,0,2,1,0,0,0,
2,4,0,0,0,1,0,2,1,2,0,0,
2,4,0,0,0,1,1,0,2,0,0,0,
2,4,0,0,0,1,1,1,2,1,0,0,
2,4,0,0,1,0,1,1,1,2,0,0,
2,4,0,0,1,0,2,0,2,1,0,0,
2,4,0,1,1,1,2,0,2,1,0,0,
2,4,0,2,1,0,1,1,1,2,0,0,
3,4,0,0,0,1,1,0,1,1,0,0,
4,5,0,0,0,1,0,2,1,0,2,0,
4,5,0,0,0,1,0,2,1,2,2,2,
4,5,0,0,1,0,2,0,2,1,2,2,
4,5,0,2,1,2,2,0,2,1,2,2,
5,5,0,0,0,1,0,2,0,3,1,1,
5,5,0,0,0,1,0,2,0,3,1,2,
5,5,0,0,1,0,1,1,2,0,3,0,
5,5,0,0,1,0,2,0,2,1,3,0,
5,5,0,1,1,0,1,1,1,2,1,3,
5,5,0,1,1,0,1,1,2,1,3,1,
5,5,0,1,1,1,2,0,2,1,3,1,
5,5,0,2,1,0,1,1,1,2,1,3,
6,5,0,0,0,1,0,2,1,0,1,2,
6,5,0,0,0,1,1,0,2,0,2,1,
6,5,0,0,0,1,1,1,2,0,2,1,
6,5,0,0,0,2,1,0,1,1,1,2,
7,5,0,0,0,1,0,2,1,0,1,1,
7,5,0,0,0,1,0,2,1,1,1,2,
7,5,0,0,0,1,1,0,1,1,1,2,
7,5,0,0,0,1,1,0,1,1,2,0,
7,5,0,0,0,1,1,0,1,1,2,1,
7,5,0,0,1,0,1,1,2,0,2,1,
7,5,0,1,0,2,1,0,1,1,1,2,
7,5,0,1,1,0,1,1,2,0,2,1,
8,5,0,0,0,1,0,2,1,2,1,3,
8,5,0,0,0,1,1,1,1,2,1,3,
8,5,0,0,1,0,1,1,2,1,3,1,
8,5,0,0,1,0,2,0,2,1,3,1,
8,5,0,1,0,2,0,3,1,0,1,1,
8,5,0,1,1,0,1,1,2,0,3,0,
8,5,0,1,1,1,2,0,2,1,3,0,
8,5,0,2,0,3,1,0,1,1,1,2,
9,5,0,1,1,0,1,1,1,2,2,1,
10,5,0,0,0,1,1,1,1,2,2,2,
10,5,0,0,1,0,1,1,2,1,2,2,
10,5,0,1,0,2,1,0,1,1,2,0,
10,5,0,2,1,1,1,2,2,0,2,1,
11,5,0,0,0,1,0,2,0,3,1,0,
11,5,0,0,0,1,0,2,0,3,1,3,
11,5,0,0,0,1,1,0,2,0,3,0,
11,5,0,0,0,1,1,1,2,1,3,1,
11,5,0,0,1,0,1,1,1,2,1,3,
11,5,0,0,1,0,2,0,3,0,3,1,
11,5,0,1,1,1,2,1,3,0,3,1,
11,5,0,3,1,0,1,1,1,2,1,3
};
#include<cstdio>
#include<cstdlib>
#include<new>
#define FOR(i,s,t)
for(ptr i=(s)->t;i!=(s);i=i->t)
const int N=3300;
const int M=67;
char s[16][16];
int q[M],v[12];
typedef struct node*ptr;
struct node{
ptr l,r,u,d;
int x,y;
node(){l=r=u=d=this;}
node(ptr i,ptr j){
l=i,r=i->r,u=j,d=j->d;
x=i->x,++q[y=j->y];
l->r=r->l=u->d=d->u=this;
}
}e[N*6],r[N],c[M];
ptr o=e+1,h=e,t=e;
int cal(int i,int j){return i*(i+1)/2+j;}
int xpos(int k){
for(int i=1;;++i)
if(i*(i+1)/2>k)return i-1;
}
int ypos(int k){
return k-xpos(k)*(xpos(k)+1)/2;
}
void ins(int i,int j,int k){
int s=k*55+cal(i,j);
new(o++)node(r+s,c+*f[k]+55);
for(int l=1;l<=f[k][1];++l)
new(o++)node(r+s,c+cal(i+f[k][l*2],j+f[k][l*2+1]));
}
void rem(int k){
c[k].l->r=c[k].r,c[k].r->l=c[k].l;
FOR(i,c+k,d)FOR(j,i,l)
j->u->d=j->d,j->d->u=j->u,--q[j->y];
}
void res(int k){
c[k].r->l=c[k].l->r=c+k;
FOR(i,c+k,u)FOR(j,i,l)
++q[(j->u->d=j->d->u=j)->y];
}
void dfs(int z){
static int u[12];
if(h->l==h){
for(int a=0;a!=12;++a){
int i=xpos(u[a]%55);
int j=ypos(u[a]%55);
int k=u[a]/55;
for(int l=1;l<=f[k][1];++l)
s[f[k][l*2]+i][f[k][l*2+1]+j]=*f[k]+65;
}
for(int i=0;i!=10;++i)puts(s[i]);
exit(0);
}
int s=h->l->y;
FOR(i,h,l)
if(q[s]>q[i->y])s=i->y;
rem(s);
FOR(i,c+s,d){
u[z]=i->x;
FOR(j,i,r)rem(j->y);
dfs(z+1);
FOR(j,i,l)res(j->y);
}
res(s);
}
bool jud(const int*f,int i,int j,int k){
for(int l=1;l<=f[1];++l)
if(s[f[l*2]+i][f[l*2+1]+j]!=k)return 0;
return 1;
}
int main(){
for(int i=0;i!=10;++i){
scanf("%s",s[i]);
for(int j=0;s[i][j];++j)
if(s[i][j]!=46)v[s[i][j]-65]=1;
}
for(int i=0;i!=N;++i)
(t=((t->d=r+i)->u=t)->d)->x=i;
t=((t->d=h)->u=t)->d;
for(int i=M-1;~i;--i)
(t=((t->l=c+i)->r=t)->l)->y=i;
t=((t->l=h)->r=t)->l;
for(int i=0;i!=10;++i)
for(int j=0;s[i][j];++j)
for(int k=0;k!=60;++k)
if(jud(f[k],i,j,v[*f[k]]?*f[k]+65:46))ins(i,j,k);
for(int i=0;i!=N;++i)
r[i].l->r=r[i].r,r[i].r->l=r[i].l;
dfs(0),puts("No solution");
}