您的位置:首页 > 产品设计 > UI/UE

[DLX]HDOJ4069 Squiggly Sudoku

2015-09-18 22:21 435 查看
题意:有9*9的格子

每个格子 由五部分组成:上(16)、右(32)、下(64)、左(128)、和该格的数值(0~9)

若上下左右有分割格子的线 就加上相应的数, 该格的数值若为0,则是未知 1~9 则是已知

然后根据分割线 做数独(每行、每列、每宫都是1~9)

输出无解、多解或者一个解就输出那个解

这种数独与普通3*3的数独 的唯一区别就是 宫 的划分的方式不一样

16、32、64、128这几个数很特殊 分别是$2^4$、$2^5$、$2^6$、$2^7$

也就是相应的二位数,若第4位为1,则上面有分割线

          若第5位为1,则右边有分割线

          若第6位为1,则下面有分割线

          若第7位为1,则左边有分割线

那么只要随便dfs一下确定在哪个宫里就好啦

然后把模板里 本来宫的位置是(i/3)*3+(j/3) 换成 dfs搜出来的宫的位置就好啦~

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
//const int N=2e5+5;

const int N=9; //3*3数独
const int MaxN=N*N*N+10;    // 一格能填9个数  9*9格
const int MaxM=N*N*4+10;     // 9*9*4=(9+9+9)*9+9*9    (9+9+9)是9行 9列 9格 *9是9个数 9*9是81个格子
const int maxnode=MaxN*4+MaxM+10;
int g[MaxN];
int anss;
struct DLX
{
int n, m, size;
int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
int H[MaxN], S[MaxM];  // S: 各列节点数
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;
}
}
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])
S[Col[U[D[j]]=D[U[j]]=j]]++;
L[R[c]]=R[L[c]]=c;
}
void Dance(int d)
{
if(anss>1)
return ;
if(R[0]==0)
{
for(int i=0;i<d;i++)
g[(ans[i]-1)/N]=(ans[i]-1)%N+1;
anss++;
}
int c=R[0];
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])
{
ans[d]=Row[i];
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;
int s[10][10];
int vis[10][10];
void dfs(int x,int y,int col)
{
if(x<0||x>=9||y<0||y>=9||vis[x][y]!=-1)
return ;
if((s[x][y]&(1<<7))==0)
{
vis[x][y]=col;
dfs(x,y-1, col);
}
if((s[x][y]&(1<<6))==0)
{
vis[x][y]=col;
dfs(x+1,y, col);
}
if((s[x][y]&(1<<5))==0)
{
vis[x][y]=col;
dfs(x,y+1, col);
}
if((s[x][y]&(1<<4))==0)
{
vis[x][y]=col;
dfs(x-1,y, col);
}
}

void palce(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k)
{
r=(i*N+j)*N+k;  // 第几行
c1=i*N+j+1;     //  第几个格子
c2=N*N+i*N+k;   // 第i行上的k
c3=N*N*2+j*N+k; // 第j列上的k
c4=N*N*3+(vis[i][j])*N+k; // 某宫中的k;
}

int main()
{
int t, ca=1;
scanf("%d", &t);
while(t--)
{
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
scanf("%d", &s[i][j]);
int num=0;
memset(vis, -1, sizeof(vis));
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
if(vis[i][j]==-1)
dfs(i, j, num++);
if((s[i][j]-(1<<7))>=0)
s[i][j]-=1<<7;
if((s[i][j]-(1<<6))>=0)
s[i][j]-=1<<6;
if((s[i][j]-(1<<5))>=0)
s[i][j]-=1<<5;
if((s[i][j]-(1<<4))>=0)
s[i][j]-=1<<4;
}
dlx.init(N*N*N, 4*N*N);
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
for(int k=1; k<=9; k++)
if(s[i][j]==0 || s[i][j]==k)
{
int r, c1, c2, c3, c4;
palce(r, c1, c2, c3, c4, i, j, k);
dlx.Link(r, c1);
dlx.Link(r, c2);
dlx.Link(r, c3);
dlx.Link(r, c4);
}
anss=0;
dlx.Dance(0);
printf("Case %d:\n", ca++);
if(anss==0)
puts("No solution");
else if(anss>1)
puts("Multiple Solutions");
else
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
printf("%d", g[i*N+j]);
puts("");
}
}
}
return 0;
}


HDOJ 4069
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: