Sudoku(九宫格问题)
2013-07-08 16:52
337 查看
Sudoku(POJ2676)是一种简单的数字游戏,一个9×9的正方形表格被分成9个3×3的小正方形表格,在表格的某些单元格中,已填有数字1至9中的一个。游戏的任务是,在表格每一个空白单元格里填入数字1至9中的一个,使得9×9正方形表格的每一行和每一列以及9个3×3小正方形表格中,数字1至9都出现且仅出现一次。
你的任务是,编程求出给定Sudoku游戏的一种填法。例如,图1(a)游戏的一个解如图1(b)所示。
(a)
(b)
思路:用深搜法,两种方法,后一种是对前一种的优化。
代码如下:
我们可以对以上代码进行优化,不需要每一个位置都要遍历,只遍历未填充数字的位置,代码如下:
你的任务是,编程求出给定Sudoku游戏的一种填法。例如,图1(a)游戏的一个解如图1(b)所示。
1 | 3 | 5 | 9 | |||||
2 | 1 | 9 | 4 | |||||
7 | 4 | |||||||
3 | 5 | 2 | 6 | |||||
6 | 5 | |||||||
7 | 8 | 3 | 4 | |||||
4 | 1 | |||||||
9 | 2 | 5 | 8 | |||||
8 | 4 | 1 | 7 |
1 | 4 | 3 | 6 | 2 | 8 | 5 | 7 | 9 |
5 | 7 | 2 | 1 | 3 | 9 | 4 | 6 | 8 |
9 | 8 | 6 | 7 | 5 | 4 | 2 | 3 | 1 |
3 | 9 | 1 | 5 | 4 | 2 | 7 | 8 | 6 |
4 | 6 | 8 | 9 | 1 | 7 | 3 | 5 | 2 |
7 | 2 | 5 | 8 | 6 | 3 | 9 | 1 | 4 |
2 | 3 | 7 | 4 | 8 | 1 | 6 | 9 | 5 |
6 | 1 | 9 | 2 | 7 | 5 | 8 | 4 | 3 |
8 | 5 | 4 | 3 | 9 | 6 | 1 | 2 | 7 |
思路:用深搜法,两种方法,后一种是对前一种的优化。
代码如下:
#include <iostream> using namespace std; int map[10][10];//九宫格 //row[i][x] 标记在第i行中数字x是否出现了 //col[j][y] 标记在第j列中数字y是否出现了 //box[k][z] 标记在第k个3*3子格中数字z是否出现了 bool row[10][10],col[10][10],box[10][10]; bool DFS(int x,int y) { if (x == 10) return true; bool flag = false; if (map[x][y]) { if (y == 9) flag = DFS(x + 1,1); else flag = DFS(x,y + 1); if (flag)//回溯 return true; else return false; } else { int k = 3 * ((x - 1) / 3) + (y - 1) / 3 + 1; for (int i = 1; i <= 9; i++) if (!row[x][i] && !col[y][i] && !box[k][i]) { map[x][y] = i; row[x][i] = true; col[y][i] = true; box[k][i] = true; if (9 == y) flag = DFS(x + 1,1); else flag = DFS(x,y + 1); if (!flag)//回溯 { map[x][y] = 0; row[x][i] = false; col[y][i] = false; box[k][i] = false; } else return true; } } return false; } int main() { int T,i,j; cin>>T; while (T--) { memset(row,false,sizeof(row)); memset(col,false,sizeof(col)); memset(box,false,sizeof(box)); for (i = 1; i <= 9; i++) for (j = 1; j <= 9; j++) { cin>>map[i][j]; if (map[i][j]) { int k = 3 * ((i - 1) / 3) + (j - 1) / 3 + 1; row[i][map[i][j]] = true; col[j][map[i][j]] = true; box[k][map[i][j]] = true; } } DFS(1,1); for (i = 1; i <= 9; i++) { for (j = 1; j <= 9; j++) cout<<map[i][j]; cout<<endl; } } return 0; }
我们可以对以上代码进行优化,不需要每一个位置都要遍历,只遍历未填充数字的位置,代码如下:
#include <cstdio> #include <cstring> int row[9][10],col[9][10],box[9][10]; int map[9][9],pos[81][2],p,n;//place记录哪些位置需要填写 int DFS(int x,int y) { int i,j; if (p == n) { for (i = 0 ; i < 9; i++) { for (j = 0; j < 9;j++) printf("%d",map[i][j]); printf("\n"); } return 1; } for (i = 1 ; i <= 9; i++) if (!row[x][i] && !col[y][i] && !box[x / 3 * 3 + y / 3][i]) { map[x][y] = i; row[x][i] = col[y][i] = box[x / 3 * 3 + y / 3][i] = 1; p++; if (DFS(pos[p][0],pos[p][1])) return 1; p--; map[x][y] = 0; row[x][i] = col[y][i] = box[x / 3 * 3 + y / 3][i] = 0; } return 0; } int main() { int i,j,T; scanf("%d",&T); while (T--) { p = 0; memset(row,0,sizeof(row)); memset(col,0,sizeof(col)); memset(box,0,sizeof(box)); for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { scanf("%d",&map[i][j]); if (map[i][j]) { row[i][map[i][j]] = 1; col[j][map[i][j]] = 1; box[i / 3 * 3 + j / 3][map[i][j]] = 1; } else { pos[p][0] = i; pos[p][1] = j; p++; } } } n = p; p = 0; DFS(pos[0][0],pos[0][1]); } return 0; }
相关文章推荐
- 八数码问题: 八数码的游戏 九宫格里面放入8个数字 启发式搜索(1)
- Java解世界最难九宫格问题
- 2016/1/10 作业 1, 二维数组遍历输出求和 2,转置运算???? 3,九宫格?? 后两个存在问题
- unity中使用九宫格输入中文的问题
- 更完美的《iOS中textField、textView判断过滤禁用emoji表情》,解决过滤表情后九宫格输入不了问题
- 数独问题的介绍及POJ 2676-Sudoku(dfs+剪枝)
- recycleview实现九宫格图片加载不全的问题
- c程序(打印日历、数转成素数乘积、猜随机数、九宫格,汉诺塔问题、main中命令行参数)
- java编程-九宫格问题
- Leetecode 36 37 Sudoku问题
- POJ 3074 Sudoku 转化精确覆盖问题DLX
- POJ 3076 Sudoku 精确覆盖问题DLX
- 关于UITextField 支持中文、英文和数字的限制问题,以及中文九宫格无法输入的解决
- sudoku-------九宫格
- Sudoku 数独问题(dfs)
- [2016/11/25]九宫格问题
- 九宫格问题(回溯的多种写法,Go语言实现)
- hdu 1426 Sudoku Killer(DFS 数独问题)
- 练习二 1026 神奇的九宫格问题
- [DFS]poj 2676 Sudoku 数独问题