zoukankan      html  css  js  c++  java
  • POJ3074 Sudoku

    Sudoku
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 10745   Accepted: 3850

    Description

    In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

    . 2 7 3 8 . . 1 .
    . 1 . . . 6 7 3 5
    . . . . . . . 2 9
    3 . 5 6 9 2 . 8 .
    . . . . . . . . .
    . 6 . 1 7 4 5 . 3
    6 4 . . . . . . .
    9 5 1 8 . . . 7 .
    . 8 . . 6 5 3 4 .

    Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

    Input

    The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

    Output

    For each test case, print a line representing the completed Sudoku puzzle.

    Sample Input

    .2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
    ......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
    end

    Sample Output

    527389416819426735436751829375692184194538267268174593643217958951843672782965341
    416837529982465371735129468571298643293746185864351297647913852359682714128574936


    题目大意:
      数独求解


    分析:
        这道题的数据强于POJ2676
      所以一般的DFS是TLE的
      但本蒟蒻又不会dancing links
      所以学习了一种类似于状态压缩的方法来判断每一行,每一列,每一个九宫格的数字使用情况
      我们可以对于每一行,每一列,每一个九宫格都用一个9位二进制数来存储,再使用bitset来将可以使用的数字取出
      (对于每一个空位优先搜索可用数字少的,可以加快速度
      最后DFS


    代码如下
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<string.h>
     4 using namespace std;
     5 int heng[10];
     6 int shu[10];
     7 int ge[10];
     8 int cnt[512],num[512],tot;
     9 char ss[10][10];
    10 char s[100];
    11 int ID(int x,int y)
    12 {
    13     return ((x/3)*3)+(y/3);
    14 }
    15 void visit(int x,int y,int z)
    16 {
    17     heng[x]^=1<<z;
    18     shu[y]^=1<<z;
    19     ge[ID(x,y)]^=1<<z;
    20 }
    21 bool dfs(int now)
    22 {
    23     if(now==0)return true;
    24     int temp=10,x,y;
    25     for(int i=0;i<9;i++)
    26     {
    27         for(int j=0;j<9;j++)
    28         {
    29             if(ss[i][j]!='.')continue;
    30             int v=heng[i]&shu[j]&ge[ID(i,j)];
    31             if(!v)return false;
    32             if(cnt[v]<temp)
    33             {
    34                 temp=cnt[v];
    35                 x=i,y=j;
    36             }
    37         }
    38     }//可用数字最少的空位
    39     int v=heng[x]&shu[y]&ge[ID(x,y)];
    40     for( ;v ;v-=v&-v)
    41     {
    42         int z=num[v&-v];
    43         ss[x][y]='1'+z;
    44         visit(x,y,z);
    45         if(dfs(now-1))return true;
    46         visit(x,y,z);
    47         ss[x][y]='.';
    48     }//取出数字再DFS
    49     return false;
    50 }
    51 int main()
    52 {
    53     for(int i=0;i<1<<9;i++)
    54     {
    55         for(int j=i;j;j-=j&-j)cnt[i]++;
    56     }
    57     for(int i=0;i<9;i++)
    58     {
    59         num[1<<i]=i;
    60     }
    61     while(scanf("%s",s)&&s[0]!='e')
    62     {
    63         for(int i=0;i<9;i++)
    64         {
    65             for(int j=0;j<9;j++)
    66             {
    67                 ss[i][j]=s[i*9+j];
    68             }
    69         }
    70         for(int i=0;i<9;i++)
    71         {
    72             heng[i]=shu[i]=ge[i]=(1<<9)-1;
    73         }
    74         tot=0;
    75         for(int i=0;i<9;i++)
    76         {
    77             for(int j=0;j<9;j++)
    78             {
    79                 if(ss[i][j]!='.')visit(i,j,ss[i][j]-'1');
    80                 else tot++;
    81             }
    82         }
    83         dfs(tot);
    84         for(int i=0;i<9;i++)
    85         {
    86             for(int j=0;j<9;j++)
    87             {
    88                 s[i*9+j]=ss[i][j];
    89             }
    90         }
    91         printf("%s
    ",s);
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    优化cocos2d/x程序的内存使用和程序大小
    cocos2d-x移植:xcode到eclipse
    程序员在编程工作中痛苦的压抑着自己某些强烈的情绪
    C++语言的一些问题
    基数排序-图非常清晰明了
    【Cocos2d-X(1.x 2.x) 修复篇】iOS6 中 libcurl.a 无法通过armv7s编译以及iOS6中无法正常游戏横屏的解决方法
    《C++ Primer》笔记-inline内联函数
    走出你的舒适区
    UDP广播与多播
    测试问题反馈需要包含内容总结
  • 原文地址:https://www.cnblogs.com/xxjnoi/p/8619129.html
Copyright © 2011-2022 走看看