未AC代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int maxnode = 100010;
const int MaxM = 1010;
const int MaxN = 1010;
int anscnt=0;
int mm[10][10];
int ansmap[10][10];
int markmap[10][10];
int vis[10][10];
struct DLX
{
int n,m,size;
int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
//U D R L用来记录某个标号的节点的上下左右节点的标号
//Row Col用来记录某个标号的节点在矩阵中的行号和列号
int H[MaxN], S[MaxM];
//H是行头 S用来保存某一列中1的数量
int ansd, ans[MaxN];
void init(int _n,int _m)
{
n = _n;
m = _m;
//初始化列头
for(int i = 0;i <= m;i++)
{
S[i] = 0;
U[i] = D[i] = i;
L[i] = i-1;
R[i] = i+1;
}
R[m] = 0; L[0] = m;
size = m;
for(int i = 1;i <= n;i++)
H[i] = -1;
}
void Link(int r,int c)
{
++S[Col[++size]=c];
Row[size] = r;
D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if(H[r] < 0)H[r] = L[size] = R[size] = size;
else
{
R[size] = R[H[r]];
L[R[H[r]]] = size;
L[size] = H[r];
R[H[r]] = size;
}
}
//对某一列进行删除 同时删除列中为1的行
void remove(int c)
{
L[R[c]] = L[c]; R[L[c]] = R[c];
for(int i = D[c];i != c;i = D[i])
for(int j = R[i];j != i;j = R[j])
{
U[D[j]] = U[j];
D[U[j]] = D[j];
--S[Col[j]];
}
}
//反着恢复状态
void resume(int c)
{
for(int i = U[c];i != c;i = U[i])
for(int j = L[i];j != i;j = L[j])
{
U[D[j]]=D[U[j]]=j;
++S[Col[j]];
}
L[R[c]] = R[L[c]] = c;
}
//d为递归深度
void Dance(int d)
{
if(d>81) return;
if(anscnt>=2) return;
if(R[0] == 0)
{
anscnt++;
memcpy(ansmap,mm,sizeof(mm));
return ;
}
int c = R[0];
//一个优化 找到列中包含1最多的列 因为这样有助于减少递归深度 (很显然1多了 删掉的行也多 矩阵缩小得就快)
for(int i = R[0];i != 0;i = R[i])
if(S[i] < S[c])
c = i;
remove(c);
//搜索
for(int i = D[c];i != c;i = D[i])
{
mm[Row[i]][Col[i]]=(Row[i]-1)%9+1;
for(int j = R[i]; j != i;j = R[j])remove(Col[j]);
Dance(d+1);
for(int j = L[i]; j != i;j = L[j])resume(Col[j]);
}
resume(c);
}
};
DLX g;
bool haswall(int x,int y, int d)
{
int tmp=mm[x][y]/16;
return tmp&(1<<d);
}
void dfs(int x,int y,int id)
{
if(vis[x][y]!=0)
return;
markmap[x][y]=id;
vis[x][y]=1;
if(!haswall(x, y, 0))
{
dfs(x-1,y,id);
}
if(!haswall(x, y, 1))
{
dfs(x,y+1,id);
}
if(!haswall(x, y, 2))
{
dfs(x+1,y,id);
}
if(!haswall(x, y, 3))
{
dfs(x,y-1,id);
}
}
int main()
{
int cas;
scanf("%d",&cas);
int id=1;
for(int z=1;z<=cas;z++)
{
id=1;
anscnt=0;
memset(vis,0,sizeof(vis));
memset(markmap,0,sizeof(markmap));
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
scanf("%d",&mm[i][j]);
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
{
if(vis[i][j]==0)
dfs(i,j,id++);
}
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
mm[i][j]%=16;
g.init(729,324);
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
int id1=(i-1)*9+j;
for(int k=1;k<=9;k++)
{
if((!mm[i][j])||(mm[i][j]==k))
{
int _cx=(id1-1)*9+k;
g.Link(_cx,id1);
g.Link(_cx,81+(i-1)*9+k);
g.Link(_cx,2*9*9+(j-1)*9+k);
g.Link(_cx,3*9*9+(markmap[i][j]-1)*9+k);
}
}
}
}
g.Dance(0);
printf("Case %d:\n",z);
if(anscnt==0)
printf("No Soltions\n");
if(anscnt==1)
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
printf("%d",ansmap[i][j]);
}
printf("\n");
}
}
if(anscnt>1)
printf("Multiple Solutions\n");
}
return 0;
}
金斌的ac代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#include<map>
#include<stack>
#include<queue>
using namespace std;
const int N=9;
const int mxn=N*N*N+10;
const int mxm=4*N*N+10;
const int mx=4*mxn+mxm;
struct DLX{
int l[mx],r[mx],u[mx],d[mx];
int x[mx],y[mx];
int siz;
int ansd,ans[N*N+10],gans[N*N+10];
int h[mxn];
int s[mxm];
void init(int _n,int _m){
for(int i=0;i<=_m;i++){
u[i]=d[i]=i;
l[i]=i-1;
r[i]=i+1;
s[i]=0;
}
for(int i=1;i<=_n;i++){
h[i]=-1;
}
r[_m]=0;
l[0]=_m;
siz=_m;
ansd=0;
}
void link(int ro,int co){
//printf("%d %d\n",ro,co);
x[++siz]=ro;
y[siz]=co;
d[siz]=co;
u[siz]=u[co];
u[co]=siz;
d[u[siz]]=siz;
s[co]++;
if(h[ro]+1){
int hr=h[ro];
r[siz]=hr;
l[siz]=l[hr];
l[hr]=siz;
r[l[siz]]=siz;
}
else h[ro]=l[siz]=r[siz]=siz;
}
void removc(int c){
r[l[c]]=r[c];
l[r[c]]=l[c];
for(int i=d[c];i!=c;i=d[i])
for(int j=r[i];j!=i;j=r[j]){
u[d[j]]=u[j];
d[u[j]]=d[j];
s[y[j]]--;
}
}
void resumc(int c){
for(int i=u[c];i!=c;i=u[i])
for(int j=l[i];j!=i;j=l[j]){
u[d[j]]=d[u[j]]=j;
s[y[j]]++;
}
r[l[c]]=l[r[c]]=c;
}
void dance(int dd){
if(dd>81){
return ;
}
if(ansd>=2)return ;
if(r[0]==0){
ansd++;
for(int i=1;i<=N*N;i++){
gans[i]=ans[i];
}
return ;
}
int c=r[0];
for(int i=r[0];i!=0;i=r[i]){
if(s[i]<s[c])c=i;
}
removc(c);
for(int i=d[c];i!=c;i=d[i]){
ans[(x[i]-1)/N+1]=(x[i]-1)%N+1;
for(int j=r[i];j!=i;j=r[j])removc(y[j]);
dance(dd+1);
for(int j=l[i];j!=i;j=l[j])resumc(y[j]);
}
resumc(c);
}
}s;
int mp[N+5][N+5];
int id[N+5][N+5];
int xx[5]={-1,0,1,0};
int yy[5]={0,1,0,-1};
int w[6]={16,32,64,128,256};
int iid;
void dfs(int x,int y,int iid){
id[x][y]=iid;
for(int i=0;i<4;i++){
int nx=x+xx[i];
int ny=y+yy[i];
if(nx>=1&&nx<=N&&ny>=1&&ny<=N&&(!id[nx][ny])){
int f=mp[x][y]%w[i+1];
if(f>=w[i])continue;
dfs(nx,ny,iid);
}
}
}
int main(void)
{
int t;
while(scanf("%d",&t)!=EOF){
for(int cas=1;cas<=t;cas++){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++)
scanf("%d",&mp[i][j]);
}
memset(id,0,sizeof(id));
iid=0;
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
if(!id[i][j])
dfs(i,j,++iid);
}
}
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
mp[i][j]%=16;
}
}
s.init(N*N*N,4*N*N);
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
int id1=(i-1)*N+j;
for(int k=1;k<=N;k++){
if((!mp[i][j])||(mp[i][j]==k)){
int _cx=(id1-1)*N+k;
s.link(_cx,id1);
s.link(_cx,N*N+(i-1)*N+k);
s.link(_cx,2*N*N+(j-1)*N+k);
s.link(_cx,3*N*N+(id[i][j]-1)*N+k);
}
}
}
}
printf("Case %d:\n",cas);
s.dance(0);
if(!s.ansd)puts("No solution");
else if(s.ansd>1)puts("Multiple Solutions");
else {
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
printf("%d",s.gans[(i-1)*N+j]);
}
puts("");
}
}
}
}
return 0;
}