数独
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
数独是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个3*3宫内的数字均含1-9,不重复。 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。
有一天hrdv碰到了一道号称是世界上最难的数独的题目,作为一名合格的程序员,哪能随随便便向困难低头,于是他决定编个程序来解决它。。
-
输入
- 第一行有一个数n(0< n <100),表示有n组测试数据,每组测试数据是由一个9*9的九宫格构成,0表示对应的格子为空 输出
- 输出一个9*9的九宫格,为这个数独的答案 样例输入
-
1 0 0 5 3 0 0 0 0 0 8 0 0 0 0 0 0 2 0 0 7 0 0 1 0 5 0 0 4 0 0 0 0 5 3 0 0 0 1 0 0 7 0 0 0 6 0 0 3 2 0 0 0 8 0 0 6 0 5 0 0 0 0 9 0 0 4 0 0 0 0 3 0 0 0 0 0 0 9 7 0 0
样例输出
-
1 4 5 3 2 7 6 9 8 8 3 9 6 5 4 1 2 7 6 7 2 9 1 8 5 4 3 4 9 6 1 8 5 3 7 2 2 1 8 4 7 3 9 5 6 7 5 3 2 9 6 4 8 1 3 6 7 5 4 2 8 1 9 9 8 4 7 6 1 2 3 5 5 2 1 8 3 9 7 6 4
思路:暴力深搜就可以水过,注意有三个判断条件,1,所在的行。2,所在的列。3,所在的宫格。其中宫格这个不太好想。其他的和 普通深搜差不多,细节上的东西在代码里面注释。
代码:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include <stdio.h>
#include <string.h> int num[ 10][ 10]; ///存储整个方格 int r[ 10][ 10]; ///存储行的情况 int c[ 10][ 10]; ///存储列的情况 int tab[ 3][ 3][ 10]; ///存储3*3宫格的情况 int n, flag; void dfs( int n) { int x = n / 9; ///获取行 int y = n % 9; ///获取列 if(flag) ///优化语句 return; if(n == 81) ///说明已经全部填完 { for( int i = 0; i < 9; i++) { for( int j = 0; j < 9; j++) { printf( "%d ", num[i][j]); } printf( "\n"); } flag = 1; return; } if(num[x][y] == 0) ///为零表示还没有填数,可以考虑 { for( int k = 1; k <= 9; k++) { if(!(r[x][k] || c[y][k] || tab[x / 3][y / 3][k])) ///上面说得三个判断条件 { num[x][y] = k; ///填数 r[x][k] = c[y][k] = tab[x / 3][y / 3][k] = 1; ///对所在行,列,宫格进行标记 dfs(n + 1); num[x][y] = 0; ///回溯还原标记 r[x][k] = c[y][k] = tab[x / 3][y / 3][k] = 0; } } } else { dfs(n + 1); /// 如果已经填的有数,跳到下一个 } } int main() { scanf( "%d", &n); while(n--) { memset(r, 0, sizeof(r)); memset(c, 0, sizeof(c)); memset(tab, 0, sizeof(tab)); flag = 0; for( int i = 0; i < 9; i++) { for( int j = 0; j < 9; j++) { scanf( "%d", &num[i][j]); int t = num[i][j]; r[i][t] = 1; ///表示第i行已经出现这个数 c[j][t] = 1; ///表示第j列已经出现这个数 tab[i / 3][j / 3][t] = 1; ///表示这个宫格已经出现了这个数 } } dfs( 0); } return 0; } |