zoukankan      html  css  js  c++  java
  • [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:
    ", 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
  • 相关阅读:
    扩展GridView控件增加选择列
    Flash图片轮换/切换左右推拉效果
    Flash图片轮换/切换普通效果1
    WebForm_PostBackOptions未定义 解决方法
    SQL Server 2008无法还原日志备份或差异备份的问题解决(转)
    一个简单的C#多线程间同步的例子.[转]
    SQL2008报错:无法还原日志备份或差异备份,因为没有文件可用于前滚(转)
    C# 字符、字符串过滤,只能输入数字、中文、英文、大写、小写(转)
    C# Monitor类锁定对象
    使用SqlServer中的float类型时发现的问题(转)
  • 原文地址:https://www.cnblogs.com/Empress/p/4820509.html
Copyright © 2011-2022 走看看