Squiggly Sudoku HDU - 4069

≯℡__Kan透↙ 提交于 2019-11-29 02:22:06
Today we play a squiggly sudoku, The objective is to fill a 9*9 grid with digits so that each column, each row, and each of the nine Connecting-sub-grids that compose the grid contains all of the digits from 1 to 9. 
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 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!