[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搜出来的宫的位置就好啦~

 

  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 }
HDOJ 4069

 

posted @ 2015-09-18 22:21  Empress  阅读(...)  评论(...编辑  收藏