zoukankan      html  css  js  c++  java
  • HDOJ_ACM_Sudoku Killer

    Problem Description
    自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视。
    据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品———HDU免费七日游外加lcy亲笔签名以及同hdu acm team合影留念的机会。
    所以全球人民前仆后继,为了奖品日夜训练茶饭不思。当然也包括初学者linle,不过他太笨了又没有多少耐性,只能做做最最基本的数独题,不过他还是想得到那些奖品,你能帮帮他吗?你只要把答案告诉他就可以,不用教他是怎么做的。

    数 独游戏的规则是这样的:在一个9x9的方格中,你需要把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证, 空格中用粗线划分成9个3x3的方格也同时包含1-9这九个数字。比如有这样一个题,大家可以仔细观察一下,在这里面每行、每列,以及每个3x3的方格都 包含1-9这九个数字。

    例题:


    答案:
     

    Input
    本题包含多组测试,每组之间由一个空行隔开。每组测试会给你一个 9*9 的矩阵,同一行相邻的两个元素用一个空格分开。其中1-9代表该位置的已经填好的数,问号(?)表示需要你填的数。
     

    Output

                对于每组测试,请输出它的解,同一行相邻的两个数用一个空格分开。两组解之间要一个空行。
    对于每组测试数据保证它有且只有一个解。
     

    Sample Input
    7 1 2 ? 6 ? 3 5 8
    ? 6 5 2 ? 7 1 ? 4
    ? ? 8 5 1 3 6 7 2
    9 2 4 ? 5 6 ? 3 7
    5 ? 6 ? ? ? 2 4 1
    1 ? 3 7 2 ? 9 ? 5
    ? ? 1 9 7 5 4 8 6
    6 ? 7 8 3 ? 5 1 9
    8 5 9 ? 4 ? ? 2 3
     

    Sample Output
    7 1 2 4 6 9 3 5 8
    3 6 5 2 8 7 1 9 4
    4 9 8 5 1 3 6 7 2
    9 2 4 1 5 6 8 3 7
    5 7 6 3 9 8 2 4 1
    1 8 3 7 2 4 9 6 5
    2 3 1 9 7 5 4 8 6
    6 4 7 8 3 2 5 1 9
    8 5 9 6 4 1 7 2 3
     

    Code

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 struct Node
     5 {
     6     int x;
     7     int y;
     8 }unknown[100];   //recode the coordinate of '?'
     9 char m[10][10];  //map
    10 int row[10][10]; //recode if the num 1-9 is traversed in this row
    11 int column[10][10];//rocode if the num 1-9 is traversed in this column
    12 int grid[10][10];  //recode if the nun 1-9 is traversed in the 3*3 grid
    13 int n, flag;  //n: the num of '?'   flag: if u find it
    14 void DFS(int step)
    15 {
    16     int i, j, sx, sy;
    17     if (step == n + 1)
    18     {
    19         //print and mark flag
    20         for (i = 1; i <= 9; i++)
    21         {
    22             for (j = 1; j < 9 ; j++)
    23                 printf("%c ", m[i][j]);
    24             printf("%c\n", m[i][j]);
    25         }
    26         flag = 1;
    27     }
    28     //u can return if flag = 1
    29     if (flag == 1)
    30         return;
    31     //get the coodinate of '?'
    32     sx = unknown[step].x;
    33     sy = unknown[step].y;
    34     for (i = 1; i <= 9; i++)
    35     {
    36         //if the num is travsed in row or column or grid, u can ingore the number
    37         if (row[sx][i] == 1 || column[sy][i] == 1 || grid[(sx - 1) / 3 * 3 + (sy - 1) / 3 + 1][i] == 1)
    38             continue;
    39         //firstly remark it to 1, then deep search, if u can't get it, u should change it to 0
    40         row[sx][i] = 1;
    41         column[sy][i] = 1;
    42         grid[(sx - 1) / 3 * 3 + (sy - 1) / 3 + 1][i] = 1;
    43         m[sx][sy] = i + '0';
    44         DFS(step + 1);
    45         row[sx][i] = 0;
    46         column[sy][i] = 0;
    47         grid[(sx - 1) / 3 * 3 + (sy - 1) / 3 + 1][i] = 0;
    48     }
    49 }
    50 int main()
    51 {
    52     int i, j;
    53     int k = 1;
    54     do {
    55         //initializing
    56         memset(row, 0, sizeof(row));
    57         memset(column, 0, sizeof(column));
    58         memset(grid, 0, sizeof(grid));
    59         n = 0;
    60         flag = 0;
    61         for (i = 1; i <= 9; i++)
    62         {
    63             //this method is easier and straightforward
    64             scanf("%c %c %c %c %c %c %c %c %c", &m[i][1], &m[i][2], &m[i][3], &m[i][4], &m[i][5], &m[i][6], &m[i][7], &m[i][8], &m[i][9]);
    65             getchar();
    66             //pretreatment: get the coodinate of '?' and mark these number to 1
    67             for (j = 1; j <= 9; j++)
    68             {
    69                 if (m[i][j] == '?')
    70                 {
    71                     n++;
    72                     unknown[n].x = i;
    73                     unknown[n].y = j;
    74                 }
    75                 else
    76                 {
    77                     row[i][m[i][j] - '0'] = 1;
    78                     column[j][m[i][j] - '0'] = 1;
    79                     grid[(i - 1) / 3 * 3 + (j - 1) / 3 + 1][m[i][j] - '0'] = 1;
    80                 }
    81             }
    82         }
    83         //don't forget it, or u will get presentation Error
    84         if(k++ > 1)
    85             printf("\n");
    86         DFS(1);
    87     } while(getchar() == '\n');  //I still confuse for this
    88     return 0;
    89 }
     

    Idea

    This is normal DFS, but u should translate it. The difficult point is that limited condition, I use three array to mark if the num is traversed. Besides, u should care about the input, I find that when I use do... while, I accepted, I still confuse about it.

    Recommend
    LL
     
  • 相关阅读:
    [leetcode-79-Word Search]
    [leetcode-563-Binary Tree Tilt]
    [leetcode-561-Array Partition I]
    [leetcode-556-Next Greater Element III]
    [leetcode-554-Brick Wall]
    [leetcode-557-Reverse Words in a String III]
    [leetcode-532-K-diff Pairs in an Array]
    dev 官网
    DataTable 设置primarykey 后进行 Merge操作
    对称矩阵 一个简单的小把戏
  • 原文地址:https://www.cnblogs.com/chuanlong/p/3032749.html
Copyright © 2011-2022 走看看