• Squiggly Sudoku HDU


    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:
    No solution
    ",ans);
    253         }
    254         else if(num>1)//多解
    255         {
    256             printf("Case %d:
    Multiple Solutions
    ",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:
    ",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("
    ");
    277             }
    278         }
    279     }
    280 }
  • 相关阅读:
    CloudAlibaba
    搭建一个Vue项目
    命令合集
    luoguP3224 [HNOI2012]永无乡【线段树,并查集】
    luoguP3521 [POI2011]ROTTree Rotations【线段树】
    luoguP4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并 (线段树权值动态开点,树链剖分)
    字符串类模板及总结(随缘更新)
    codeforces600E Lomsat gelral【线段树合并/DSU】
    codeforces963D. Frequency of String【哈希】
    "蔚来杯"2022牛客暑期多校训练营9 G Magic Spells【马拉车+哈希】
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11440138.html
Copyright © 2020-2023  润新知