标签:
精确覆盖问题,用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