标签:
精确覆盖问题,用dancing links求解。
打常量表比较麻烦。
#include<bits/stdc++.h>
#define FOR(i,s,t)for(node* i=(s)->t;i!=(s);i=i->t)
const int f[60][12]={
{0,3,0,0,0,1,1,0},
{0,3,0,0,0,1,1,1},
{0,3,0,0,1,0,1,1},
{0,3,0,1,1,0,1,1},
{1,4,0,0,0,1,0,2,0,3},
{1,4,0,0,1,0,2,0,3,0},
{2,4,0,0,0,1,0,2,1,0},
{2,4,0,0,0,1,0,2,1,2},
{2,4,0,0,0,1,1,0,2,0},
{2,4,0,0,0,1,1,1,2,1},
{2,4,0,0,1,0,1,1,1,2},
{2,4,0,0,1,0,2,0,2,1},
{2,4,0,1,1,1,2,0,2,1},
{2,4,0,2,1,0,1,1,1,2},
{3,4,0,0,0,1,1,0,1,1},
{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}
};
const int N=3300,M=67;
int cnt[M];
struct node{
int s,a;
node *l,*r,*u,*d;
node():l(this){d=u=r=l;}
node(node* l,node* u)
:s(l->s),a(u->a),
l(l),r(l->r),u(u),d(u->d){
++cnt[a];
l->r=r->l=u->d=d->u=this;
}
}r[N],c[M],e[N*6],
*back=e,*h=back++,*t=h;
int hash(int i,int j){
return i*(i+1)/2+j;
}
int get_x(int v){
int i=1;
while(i*(i+1)/2<=v)
++i;
return i-1;
}
int get_y(int v){
int i=get_x(v);
return v-i*(i+1)/2;
}
void insert(int i,int j,int k){
int s=k*55+hash(i,j);
for(int z=1;z<=f[k][1];++z)
new(back++)
node(r+s,c+hash(
f[k][z<<1]+i,
f[k][z<<1|1]+j));
new(back++)
node(r+s,c+*f[k]+55);
}
void remove(int a){
c[a].l->r=c[a].r;
c[a].r->l=c[a].l;
FOR(i,c+a,d)
FOR(j,i,l){
j->u->d=j->d;
j->d->u=j->u;
--cnt[j->a];
}
}
void resume(int a){
c[a].r->l
=c[a].l->r=c+a;
FOR(i,c+a,u)
FOR(j,i,l)
++cnt[(j->u->d
=j->d->u=j)->a];
}
char s[16][16];
void dfs(int z){
static int u[12];
if(h->l==h){
for(int a=0;a!=12;++a){
int i=get_x(u[a]%55);
int j=get_y(u[a]%55);
int k=u[a]/55;
for(int x=1;x<=f[k][1];++x)
s[f[k][x<<1]+i][f[k]
[x<<1|1]+j]=*f[k]+65;
}
for(int i=0;i!=10;++i)
puts(s[i]);
exit(0);
}
int a,s=1e9;
FOR(i,h,l)
if(s>cnt[i->a])
s=cnt[a=i->a];
remove(a);
FOR(i,c+a,d){
u[z]=i->s;
FOR(j,i,r)
remove(j->a);
dfs(z+1);
FOR(j,i,l)
resume(j->a);
}
resume(a);
}
bool test(const int* v,
int i,int j,int k){
for(int a=1;a<=v[1];++a)
if(s[v[a<<1]+i]
[v[a<<1|1]+j]!=k)
return 0;
return 1;
}
int main(){
for(int i=0;i!=N;++i)
(t=((t->d=r+i)
->u=t)->d)->s=i;
t=((t->d=h)->u=t)->d;
for(int i=M-1;~i;--i)
(t=((t->l=c+i)
->r=t)->l)->a=i;
t=((t->l=h)->r=t)->l;
static bool v[12];
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!=10;++i)
for(int j=0;s[i][j];++j)
for(int k=0;k!=60;++k)
if(test(f[k],i,j,
v[*f[k]]?*f[k]+65:46))
insert(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");
}
bzoj1501: [NOI2005]智慧珠游戏 dancing links
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5496480.html