题目大意:。。还是数独,不同的是原先的九宫格约束条件变为了给定的任意形状。。。
我们跑一遍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");
}
}