[DLX]HDOJ4069 Squiggly Sudoku
题意:有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搜出来的宫的位置就好啦~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 //const int N=2e5+5; 5 6 const int N=9; //3*3数独 7 const int MaxN=N*N*N+10; // 一格能填9个数 9*9格 8 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个格子 9 const int maxnode=MaxN*4+MaxM+10; 10 int g[MaxN]; 11 int anss; 12 struct DLX 13 { 14 int n, m, size; 15 int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode]; 16 int H[MaxN], S[MaxM]; // S: 各列节点数 17 int ansd, ans[MaxN]; 18 void init(int _n, int _m) 19 { 20 n=_n; 21 m=_m; 22 for(int i=0; i<=m; i++) 23 { 24 S[i]=0; //每一列元素个数 25 U[i]=D[i]=i;//上下指针 26 L[i]=i-1; //← 27 R[i]=i+1; //→ 28 } 29 R[m]=0; //循环 最后一个指向第一个 30 L[0]=m; //第一个往前指向最后一个 31 size=m; // 节点总数 32 for(int i=1; i<=n; i++) 33 H[i]=-1; //头指针 34 } 35 void Link(int r, int c) 36 { 37 S[Col[++size]=c]++; 38 Row[size]=r; 39 D[size]=D[c]; 40 U[D[c]]=size; 41 U[size]=c; 42 D[c]=size; 43 if(H[r]<0) 44 H[r]=L[size]=R[size]=size; 45 else 46 { 47 R[size]=R[H[r]]; 48 L[R[H[r]]]=size; 49 L[size]=H[r]; 50 R[H[r]]=size; 51 } 52 } 53 void remove(int c) 54 { 55 L[R[c]]=L[c]; 56 R[L[c]]=R[c]; 57 for(int i=D[c]; i!=c; i=D[i]) 58 for(int j=R[i]; j!=i; j=R[j]) 59 { 60 U[D[j]]=U[j]; 61 D[U[j]]=D[j]; 62 S[Col[j]]--; 63 } 64 } 65 void resume(int c) 66 { 67 for(int i=U[c]; i!=c; i=U[i]) 68 for(int j=L[i]; j!=i; j=L[j]) 69 S[Col[U[D[j]]=D[U[j]]=j]]++; 70 L[R[c]]=R[L[c]]=c; 71 } 72 void Dance(int d) 73 { 74 if(anss>1) 75 return ; 76 if(R[0]==0) 77 { 78 for(int i=0;i<d;i++) 79 g[(ans[i]-1)/N]=(ans[i]-1)%N+1; 80 anss++; 81 } 82 int c=R[0]; 83 for(int i=R[0]; i!=0; i=R[i]) 84 if(S[i]<S[c]) 85 c=i; 86 remove(c); 87 for(int i=D[c]; i!=c; i=D[i]) 88 { 89 ans[d]=Row[i]; 90 for(int j=R[i]; j!=i; j=R[j]) 91 remove(Col[j]); 92 Dance(d+1); 93 for(int j=L[i]; j!=i; j=L[j]) 94 resume(Col[j]); 95 } 96 resume(c); 97 } 98 } dlx; 99 int s[10][10]; 100 int vis[10][10]; 101 void dfs(int x,int y,int col) 102 { 103 if(x<0||x>=9||y<0||y>=9||vis[x][y]!=-1) 104 return ; 105 if((s[x][y]&(1<<7))==0) 106 { 107 vis[x][y]=col; 108 dfs(x,y-1, col); 109 } 110 if((s[x][y]&(1<<6))==0) 111 { 112 vis[x][y]=col; 113 dfs(x+1,y, col); 114 } 115 if((s[x][y]&(1<<5))==0) 116 { 117 vis[x][y]=col; 118 dfs(x,y+1, col); 119 } 120 if((s[x][y]&(1<<4))==0) 121 { 122 vis[x][y]=col; 123 dfs(x-1,y, col); 124 } 125 } 126 127 void palce(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k) 128 { 129 r=(i*N+j)*N+k; // 第几行 130 c1=i*N+j+1; // 第几个格子 131 c2=N*N+i*N+k; // 第i行上的k 132 c3=N*N*2+j*N+k; // 第j列上的k 133 c4=N*N*3+(vis[i][j])*N+k; // 某宫中的k; 134 } 135 136 int main() 137 { 138 int t, ca=1; 139 scanf("%d", &t); 140 while(t--) 141 { 142 for(int i=0;i<N;i++) 143 for(int j=0;j<N;j++) 144 scanf("%d", &s[i][j]); 145 int num=0; 146 memset(vis, -1, sizeof(vis)); 147 for(int i=0;i<N;i++) 148 for(int j=0;j<N;j++) 149 { 150 if(vis[i][j]==-1) 151 dfs(i, j, num++); 152 if((s[i][j]-(1<<7))>=0) 153 s[i][j]-=1<<7; 154 if((s[i][j]-(1<<6))>=0) 155 s[i][j]-=1<<6; 156 if((s[i][j]-(1<<5))>=0) 157 s[i][j]-=1<<5; 158 if((s[i][j]-(1<<4))>=0) 159 s[i][j]-=1<<4; 160 } 161 dlx.init(N*N*N, 4*N*N); 162 for(int i=0; i<N; i++) 163 for(int j=0; j<N; j++) 164 for(int k=1; k<=9; k++) 165 if(s[i][j]==0 || s[i][j]==k) 166 { 167 int r, c1, c2, c3, c4; 168 palce(r, c1, c2, c3, c4, i, j, k); 169 dlx.Link(r, c1); 170 dlx.Link(r, c2); 171 dlx.Link(r, c3); 172 dlx.Link(r, c4); 173 } 174 anss=0; 175 dlx.Dance(0); 176 printf("Case %d:\n", ca++); 177 if(anss==0) 178 puts("No solution"); 179 else if(anss>1) 180 puts("Multiple Solutions"); 181 else 182 { 183 for(int i=0;i<N;i++) 184 { 185 for(int j=0;j<N;j++) 186 printf("%d", g[i*N+j]); 187 puts(""); 188 } 189 } 190 } 191 return 0; 192 }