题目大意:。。还是数独,不同的是原先的九宫格约束条件变为了给定的任意形状。。。
我们跑一遍floodfill 得出每一个格子属于哪一个形状
然后就是裸的数独了
这题T<=2500 绝对不能开动态 清则TLE 不清MLE 只能数组模拟
好不容易改完了 尼玛 交上去就WA
最后发现当找到一组解之后 一定要把当前的数独转移到ANS数组中 否则就会被覆盖 导致输出时错误
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct abcd{ int l,r,u,d; int x,y,num; int bottom; void del(); void restore(); }table[4000]; int head,tot,stack[4000],top; int m,n,cnt,flag,map[9][9],belong[9][9],input[9][9],ans[9][9]; void del_column(int pos) { int i,j; for(i=table[pos].u;i;i=table[i].u) { for(j=table[i].l;j;j=table[j].l) table[j].del(); for(j=table[i].r;j;j=table[j].r) table[j].del(); table[i].del(); } table[pos].del(); } inline void output() { int i,j; for(i=0;i<9;i++) { for(j=0;j<9;j++) putchar(ans[i][j]+'0'); putchar('\n'); } } void DLX() { if(!table[head].r) { memcpy(ans,map,sizeof ans); flag++; return ; } int i,mini,bottom=top,minnum=0x7fffffff; for(i=table[head].r;i;i=table[i].r) if(table[i].x<minnum) minnum=table[i].x,mini=i; for(i=table[mini].u;i;i=table[i].u) { int x=table[i].x,y=table[i].y,num=table[i].num; map[x][y]=num; del_column(x*9+y+2 ); del_column(81+x*9+num+1 ); del_column(162+y*9+num+1 ); del_column(243+(belong[x][y])*9+num+1 ); DLX(); while(top!=bottom) table[stack[top--]].restore(); if(flag>=2) return ; } } int New(int L,int R,int U,int D,int X,int Y,int Num) { ++tot; table[tot].l=L;if(L)table[L].r=tot; table[tot].r=R;if(R)table[R].l=tot; table[tot].u=U;if(U)table[U].d=tot; table[tot].d=D;if(D)table[D].u=tot; table[tot].x=X;table[tot].y=Y;table[tot].num=Num; table[tot].bottom=D; if(table[tot].bottom) table[table[tot].bottom].x++; return tot; } void abcd :: del() { if(l)table[l].r=r; if(r)table[r].l=l; if(u)table[u].d=d; if(d)table[d].u=u; if(bottom) table[bottom].x--; stack[++top]=this-table; } void abcd :: restore() { if(l)table[l].r=this-table; if(r)table[r].l=this-table; if(u)table[u].d=this-table; if(d)table[d].u=this-table; if(bottom) table[bottom].x++; } void add(int x,int y,int num) { int last=0,temp; temp=x*9+y+2 ,last=New(last,0,table[temp].u,temp,x,y,num); temp=81+x*9+num+1 ,last=New(last,0,table[temp].u,temp,x,y,num); temp=162+y*9+num+1 ,last=New(last,0,table[temp].u,temp,x,y,num); temp=243+(belong[x][y])*9+num+1,last=New(last,0,table[temp].u,temp,x,y,num); } void initialize() { int i; top=0;flag=0;cnt=0;tot=0; head=New(0,0,0,0,0,0,0); memset(map,-1,sizeof map); for(i=1;i<=81*4;i++) New(i,0,0,0,0,0,0); } void floodfill(int x,int y) { if(~map[x][y]) return ; belong[x][y]=cnt; map[x][y]=input[x][y]&15; if(~input[x][y]&16 )floodfill(x-1,y); if(~input[x][y]&32 )floodfill(x,y+1); if(~input[x][y]&64 )floodfill(x+1,y); if(~input[x][y]&128)floodfill(x,y-1); } int main() { int T,i,j,k,x,Case=0; //freopen("sudoku.in","r",stdin); //freopen("sudoku.out","w",stdout); for(cin>>T;T;T--) { initialize(); printf("Case %d:\n",++Case); for(i=0;i<9;i++) for(j=0;j<9;j++) scanf("%d",&input[i][j]); for(i=0;i<9;i++) for(j=0;j<9;j++) if(map[i][j]==-1) floodfill(i,j),cnt++; for(i=0;i<9;i++) for(j=0;j<9;j++) if(map[i][j]) add(i,j,map[i][j]); else for(k=1;k<=9;k++) add(i,j,k); DLX(); if(!flag) puts("No solution"); else if(flag==1) output(); else puts("Multiple Solutions"); } }