Left figure is the puzzle and right figure is one solution.
Now, give you the information of the puzzle, please tell me is there no solution or multiple solution or one solution.
InputThe first line is a number T(1<=T<=2500), represents the number of case. The next T blocks follow each indicates a case.
Each case contains nine lines, Each line contains nine integers.
Each module number tells the information of the gird and is the sum of up to five integers:
0~9: '0' means this gird is empty, '1' - '9' means the gird is already filled in.
16: wall to the up
32: wall to the right
64: wall to the down
128: wall to the left
I promise there must be nine Connecting-sub-grids, and each contains nine girds.OutputFor each case, if there are Multiple Solutions or no solution just output "Multiple Solutions" or "No solution". Else output the exclusive solution.(as shown in the sample output)Sample Input
3 144 18 112 208 80 25 54 144 48 135 38 147 80 121 128 97 130 32 137 32 160 144 114 167 208 0 32 192 100 160 160 208 96 183 192 101 209 80 39 192 86 48 136 80 114 152 48 226 144 112 160 160 149 48 128 0 112 166 215 96 160 128 41 128 39 153 32 209 80 101 136 35 192 96 200 67 80 112 208 68 96 144 48 144 81 81 16 53 144 48 128 96 224 144 48 128 103 128 38 163 208 80 0 37 224 209 0 32 135 48 176 192 64 112 176 192 104 192 101 128 89 80 82 32 150 48 149 48 224 208 16 48 224 192 33 128 0 114 176 135 0 80 112 169 137 32 148 32 192 96 176 144 32 192 96 193 64 80 80 96 192 96 144 88 48 217 16 16 80 112 176 224 176 129 48 128 40 208 16 37 145 32 128 96 196 96 176 136 32 192 32 227 176 144 80 96 192 32 176 192 80 98 160 145 80 48 224 128 48 144 80 96 224 183 128 48 128 36 224 144 51 144 32 128 105 131 64 112 136 32 192 36 224 176 224 208 80 64 64 116 192 83 96
Sample Output
Case 1: 521439678 763895124 984527361 346182795 157964832 812743956 235678419 479216583 698351247 Case 2: No solution Case 3: Multiple Solutions题意:一个数独求解,与一般数独不同的是此数独用墙把81个数分成了9 个宫,每个宫都有1到9 。样例中每个数独的数最多是由四个墙和本身的数组成对于输出,数独无解则输出无解,有多个解则输出多个解,右一个解则输出补全的数独。思路:与一般的数独解法大致相同,不同的是此题首先用搜索将数独中的数分好宫,然后是当有解时,保存答案。代码:
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 1000000007 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 const int maxn=10240; 22 struct DLX 23 { 24 int n,id; 25 int L[maxn],R[maxn],U[maxn],D[maxn]; 26 int C[maxn],S[maxn],loc[maxn][3];//C代表列,S代表每列有的数字数量,loc代表这个数在数独中的位置和数值 27 int H[maxn],ans[maxn],ansed;//ansed表示解的个数,ans记录答案 28 int fans[maxn],fansed;//复制的ansed,ans数组 29 void init(int nn) 30 { 31 n=nn; 32 for(int i=0;i<=n;i++) 33 { 34 U[i]=D[i]=i; 35 L[i]=i-1; 36 R[i]=i+1; 37 } 38 L[0]=n; R[n]=0; 39 id=n; 40 ansed=0; 41 fansed=0; 42 memset(S,0,sizeof(S)); 43 memset(H,-1,sizeof(H)); 44 } 45 void Link(int x,int y,int px,int py,int k) 46 { 47 ++id; 48 D[id]=y; U[id]=U[y]; 49 D[U[y]]=id; U[y]=id; 50 loc[id][0]=px,loc[id][1]=py,loc[id][2]=k;//存放数的位置和数 51 C[id]=y; 52 S[y]++;//此列1的数量加一 53 if(H[x]==-1) H[x]=L[id]=R[id]=id; 54 else 55 { 56 int a=H[x]; 57 int b=R[a]; 58 L[id]=a; R[a]=id; 59 R[id]=b; L[b]=id; 60 H[x]=id; 61 } 62 } 63 void Remove(int c) 64 { 65 L[R[c]]=L[c]; 66 R[L[c]]=R[c]; 67 for(int i=D[c];i!=c;i=D[i]) 68 { 69 for(int j=R[i];j!=i;j=R[j]) 70 { 71 U[D[j]]=U[j]; 72 D[U[j]]=D[j]; 73 S[C[j]]--; 74 } 75 } 76 } 77 void Resume(int c) 78 { 79 for(int i=U[c];i!=c;i=U[i]) 80 for(int j=R[i];j!=i;j=R[j]) 81 { 82 S[C[j]]++; 83 U[D[j]]=j; 84 D[U[j]]=j; 85 } 86 L[R[c]]=c; 87 R[L[c]]=c; 88 } 89 void fuzhi()//复制已经得到的数独, 90 { 91 fansed=ansed; 92 for(int i=0;i<81;i++) 93 { 94 fans[i]=ans[i]; 95 } 96 } 97 void dfs(int step) 98 { 99 if(R[0]==0&&step==81) 100 { 101 ansed++; 102 fuzhi(); 103 return ; 104 } 105 int c=R[0]; 106 for(int i=R[0];i;i=R[i])//优先循环1的数量少的一列 107 { 108 if(S[i]<S[c]) 109 { 110 c=i; 111 } 112 } 113 Remove(c); 114 for(int i=D[c];i!=c;i=D[i]) 115 { 116 ans[step]=i; 117 for(int j=R[i];j!=i;j=R[j]) Remove(C[j]); 118 dfs(step+1); 119 if(ansed>=2)//当解多于两个时已是多解,不需要再循环了 120 { 121 return ; 122 } 123 for(int j=L[i];j!=i;j=L[j]) Resume(C[j]); 124 } 125 Resume(c); 126 } 127 }dlx; 128 struct node 129 { 130 int fxi[4],gong;//fxi表示四个方向,gong表示所在的第几宫 131 int x,y,num;//x,y表示行列,num表示数 132 }; 133 node sd[10][10]; 134 int bj[10][10]; 135 int fx[4]={0,1,0,-1},fy[4]={-1,0,1,0}; 136 void bfs(int x,int y,int z)//搜索同一宫的位置 137 { 138 queue<node> qu; 139 node no=sd[x][y]; 140 bj[x][y]=1; 141 qu.push(no); 142 while(!qu.empty()) 143 { 144 no=qu.front(); 145 qu.pop(); 146 for(int k=0;k<4;k++) 147 { 148 int i=no.x+fx[k]; 149 int j=no.y+fy[k]; 150 if(!no.fxi[k]&&bj[i][j]==0)//没有墙并且没走过 151 { 152 sd[i][j].gong=z; 153 bj[i][j]=1; 154 node s=sd[i][j]; 155 qu.push(s); 156 } 157 } 158 } 159 } 160 int main() 161 { 162 int t,ans=0;//ans表示第几个测试任务 163 scanf("%d",&t); 164 while(t--) 165 { 166 ans++; 167 memset(sd,0,sizeof(sd)); 168 int js=0; 169 dlx.init(81*4); 170 for(int i=0;i<9;i++) 171 { 172 for(int j=0;j<9;j++) 173 { 174 scanf("%d",&sd[i][j].num); 175 sd[i][j].x=i; 176 sd[i][j].y=j; 177 if(sd[i][j].num>=128)//左 178 { 179 sd[i][j].num-=128; 180 sd[i][j].fxi[0]=1; 181 } 182 if(sd[i][j].num>=64)//下 183 { 184 sd[i][j].num-=64; 185 sd[i][j].fxi[1]=1; 186 } 187 if(sd[i][j].num>=32)//右 188 { 189 sd[i][j].num-=32; 190 sd[i][j].fxi[2]=1; 191 } 192 if(sd[i][j].num>=16)//上 193 { 194 sd[i][j].num-=16; 195 sd[i][j].fxi[3]=1; 196 } 197 } 198 } 199 js=0; 200 memset(bj,0,sizeof(bj)); 201 for(int i=0;i<9;i++) 202 { 203 for(int j=0;j<9;j++) 204 { 205 if(bj[i][j]==0)//循环所有数独 206 { 207 bfs(i,j,js); 208 sd[i][j].gong=js; 209 js++; 210 } 211 } 212 } 213 for(int i=0;i<9;i++) 214 { 215 for(int j=0;j<9;j++) 216 { 217 int a,b,c,d; 218 if(sd[i][j].num==0) 219 { 220 for(int k=1;k<=9;k++) 221 { 222 a=i*9+j+1; 223 b=i*9+k+81; 224 c=j*9+k+81+81; 225 d=sd[i][j].gong*9+k+81+81+81; 226 js++; 227 dlx.Link(js,a,i,j,k); 228 dlx.Link(js,b,i,j,k); 229 dlx.Link(js,c,i,j,k); 230 dlx.Link(js,d,i,j,k); 231 } 232 } 233 else 234 { 235 int k=sd[i][j].num; 236 a=i*9+j+1; 237 b=i*9+k+81; 238 c=j*9+k+81+81; 239 d=sd[i][j].gong*9+k+81+81+81; 240 js++; 241 dlx.Link(js,a,i,j,k); 242 dlx.Link(js,b,i,j,k); 243 dlx.Link(js,c,i,j,k); 244 dlx.Link(js,d,i,j,k); 245 } 246 } 247 } 248 dlx.dfs(0); 249 int num=dlx.fansed; 250 if(num==0)//无解 251 { 252 printf("Case %d:\nNo solution\n",ans); 253 } 254 else if(num>1)//多解 255 { 256 printf("Case %d:\nMultiple Solutions\n",ans); 257 } 258 else//一个解 259 { 260 int no[10][10]; 261 for(int i=0;i<81;i++) 262 { 263 int a=dlx.fans[i]; 264 int x=dlx.loc[a][0]; 265 int y=dlx.loc[a][1]; 266 int k=dlx.loc[a][2]; 267 no[x][y]=k; 268 } 269 printf("Case %d:\n",ans); 270 for(int i=0;i<9;i++) 271 { 272 for(int j=0;j<9;j++) 273 { 274 printf("%d",no[i][j]); 275 } 276 printf("\n"); 277 } 278 } 279 } 280 }