• poj 3074


    题意:解数独

    分析:

    完整的数独有四个充要条件:

    1.每个格子都有填数字

    2.每列都有1~9中的每个数字

    3.每行都有1~9中的每个数字

    4.每个9宫格都有1~9中的每个数字

    可以转化成精确覆盖问题。每行表示一个格子的一种填法,1~81列表示这个格子的位置,82~162列表示这是哪一行的什么数字,163~243列表示这是哪一列的什么数字,244~324列表示这是哪一个九宫格里的什么数字。每行都把四个1填入这四个区间里的对应位置。最后求出这个01矩阵的精确覆盖就是解。

    在DFS里删除列的顺序为由左往右时TLE了,由右向左却AC,什么原因???

      1 #include <cstdio>
      2 #include <cstring>
      3 int U[240005],D[240005],L[240005],R[240005],row[800],col[800],cont[800];
      4 int X[240005],Y[240005],H[800],S[350],M,N,sz,ans[9][9];
      5 bool hashr[10][10],hashc[10][10],hashp[10][10];
      6 void init(int m)
      7 {
      8     for(int i = 0;i <= m;i++)
      9     {
     10         U[i] = D[i] = i;
     11         L[i + 1] = i;
     12         R[i] = i + 1;
     13         S[i] = 0;
     14     }
     15     R[m] = 0;
     16     L[0] = m;
     17     sz = m + 1;
     18 }
     19 
     20 void remove(int c)
     21 {
     22     //删除一整列
     23     R[L[c]] = R[c];
     24     L[R[c]] = L[c];
     25     //删除行
     26     for(int i = D[c];i != c;i = D[i])
     27     {
     28         for(int j = R[i];j != i;j = R[j])
     29         {
     30             D[U[j]] = D[j];
     31             U[D[j]] = U[j];
     32             S[X[j]]--;
     33         }
     34     }
     35 }
     36 
     37 void resume(int c)
     38 {
     39     //恢复一整列
     40     L[R[c]] = c;
     41     R[L[c]] = c;
     42     //恢复行
     43     for(int i = U[c];i != c;i = U[i])
     44     {
     45         for(int j = L[i];j != i;j = L[j])
     46         {
     47             D[U[j]] = j;
     48             U[D[j]] = j;
     49             S[X[j]]++;
     50         }
     51     }
     52 }
     53 
     54 void ins(int r,int c)
     55 {
     56     S[c]++;
     57     //纵向插入
     58     D[U[c]] = sz;
     59     U[sz] = U[c];
     60     D[sz] = c;
     61     U[c] = sz;
     62     X[sz] = c;
     63     Y[sz] = r;
     64     //横向插入
     65     if(H[r] == -1)
     66     {
     67         H[r] = L[sz] = R[sz] = sz;
     68     }
     69     else
     70     {
     71         R[L[H[r]]] = sz;
     72         L[sz] = L[H[r]];
     73         R[sz] = H[r];
     74         L[H[r]] = sz;
     75     }
     76     sz++;
     77 }
     78 
     79 bool dfs(int k)
     80 {
     81     if(R[0] == 0)
     82     {
     83         return true;
     84     }
     85     else
     86     {
     87         int m = 0xfffffff,num;
     88         for(int i = R[0];i != 0;i = R[i])
     89         {
     90             if(S[i] == 0)
     91             {
     92                 return false;
     93             }
     94             if(m > S[i])
     95             {
     96                 m = S[i];
     97                 num = i;
     98                 if(m == 1)
     99                 {
    100                     break;
    101                 }
    102             }
    103         }
    104         remove(num);
    105         for(int i = D[num];i != num;i = D[i])
    106         {
    107             ans[row[Y[i]]][col[Y[i]]] = cont[Y[i]];
    108             for(int j = R[i];j != i;j = R[j])
    109             {
    110                 remove(X[j]);
    111             }
    112             if(dfs(k + 1))
    113             {
    114                 return true;
    115             }
    116             for(int j = L[i];j != i;j = L[j])//恢复顺序改为由左向右居然慢N倍?!
    117             {
    118                 resume(X[j]);
    119             }
    120         }
    121         resume(num);
    122     }
    123     return false;
    124 }
    125 
    126 int main()
    127 {
    128     char input[90];
    129     while(scanf("%s",input),input[0] != 'e')
    130     {
    131         memset(hashr,false,sizeof(hashr));
    132         memset(hashc,false,sizeof(hashc));
    133         memset(hashp,false,sizeof(hashp));
    134         for(int i = 0;i < 9;i++)
    135         {
    136             for(int j = 0;j < 9;j++)
    137             {
    138                 if(input[i * 9 + j] != '.')
    139                 {
    140                     hashr[i][input[i * 9 + j] - '0'] = true;
    141                     hashc[j][input[i * 9 + j] - '0'] = true;
    142                     hashp[i / 3 * 3 + j / 3][input[i * 9 + j] - '0'] = true;
    143                 }
    144             }
    145         }
    146         M = 4 * 9 * 9;
    147         N = 0;
    148         init(M);
    149         for(int i = 0;i < 9;i++)
    150         {
    151             for(int j = 0;j < 9;j++)
    152             {
    153                 int k;
    154                 if(input[i * 9 + j] != '.')
    155                 {
    156                     k = input[i * 9 + j] - '0';
    157                 }
    158                 else
    159                 {
    160                     k = 0;
    161                 }
    162                 if(k != 0)
    163                 {
    164                     row[N] = i;
    165                     col[N] = j;
    166                     cont[N] = k;
    167                     H[N] = -1;
    168                     ins(N,i * 9 + j + 1);//(i,j)位置已填数字
    169                     ins(N,81 + i * 9 + k);//i行已有k
    170                     ins(N,162 + j * 9 + k);//j列已有k
    171                     ins(N++,243 + (i / 3 * 3 + j / 3) * 9 + k);//宫格已有k
    172                 }
    173                 else
    174                 {
    175                     for(k = 1;k <= 9;k++)
    176                     {
    177                         if(!hashr[i][k] && !hashc[j][k] && !hashp[i / 3 * 3 + j / 3][k])
    178                         {
    179                             row[N] = i;
    180                             col[N] = j;
    181                             cont[N] = k;
    182                             H[N] = -1;
    183                             ins(N,i * 9 + j + 1);//(i,j)位置已填数字
    184                             ins(N,81 + i * 9 + k);//i行已有k
    185                             ins(N,162 + j * 9 + k);//j列已有k
    186                             ins(N++,243 + (i / 3 * 3 + j / 3) * 9 + k);//宫格已有k
    187                         }
    188                     }
    189                 }
    190             }
    191         }
    192         dfs(0);
    193         for(int i = 0;i < 9;i++)
    194         {
    195             for(int j = 0;j < 9;j++)
    196             {
    197                 printf("%d",ans[i][j]);
    198             }
    199         }
    200         printf("
    ");
    201     }
    202     return 0;
    203 }
  • 相关阅读:
    ssh 私匙登录, 文件rswrst权限
    从内存使用的角度来理解.Net底层架构
    (转)C#为什么要使用Invoke,它和BeginInvoke有什么区别
    如何通过微信自定义菜单跳转到自己的网站
    (转)HubbleDotNet+Mongodb 构建高性能搜索引擎--概述
    (转)HubbleDotNet 和 Lucene.net 性能对比测试
    C#异步提示和技巧
    关于System.Windows.Forms.DateTimePicker的一个Bug
    关于frameset中指定区域回退的实现
    java.lang.NoClassDefFoundError Adding a jar to an RCP application
  • 原文地址:https://www.cnblogs.com/ZShogg/p/3290922.html
Copyright © 2020-2023  润新知