poj_2676
来源:互联网 发布:网络摄像机英文怎么说 编辑:程序博客网 时间:2024/06/04 08:32
大致题意:
九宫格问题,也有人叫数独问题
把一个9行9列的网格,再细分为9个3*3的子网格,要求每行、每列、每个子网格内都只能使用一次1~9中的一个数字,即每行、每列、每个子网格内都不允许出现相同的数字。
0是待填位置,其他均为已填入的数字。
要求填完九宫格并输出(如果有多种结果,则只需输出其中一种)
如果给定的九宫格无法按要求填出来,则输出原来所输入的未填的九宫格
解题思路:
DFS试探,失败则回溯
用三个数组进行标记每行、每列、每个子网格已用的数字,用于剪枝
bool row[10][10]; //row[i][x] 标记在第i行中数字x是否出现了
bool col[10][10]; //col[j][y] 标记在第j列中数字y是否出现了
bool grid[10][10]; //grid[k][x] 标记在第k个3*3子格中数字z是否出现了
row 和 col的标记比较好处理,关键是找出grid子网格的序号与 行i列j的关系
即要知道第i行j列的数字是属于哪个子网格的
首先我们假设子网格的序号如下编排:
由于1<=i、j<=9,我们有: (其中“/”是C++中对整数的除法)
令a= i/3 , b= j/3 ,根据九宫格的 行列 与 子网格 的 关系,我们有:
不难发现 3a+b=k
即 3*(i/3)+j/3=k
有了这个推导的关系式,问题的处理就变得非常简单了,直接DFS即可
(以上是神牛的思路,只要是grid数组适用的太精辟了)
#include <iostream>#include <cstring>#include <cstdio>using namespace std;#pragma warning(disable : 4996)int n;int map[10][10];bool row[10][10]; //记录每行的数字是否可行bool col[10][10]; //记录没列的数字是否可行bool grid[10][10]; //记录每个九宫格的数字是否可行void CreateMap(){char str[10] = {0};for(int i = 0; i < 9; i++){scanf("%s", str);for(int j = 0; j < 9; j++){map[i][j] = str[j] - '0';if(map[i][j] != 0){int num = map[i][j];int k = 3 * (i / 3) + j / 3; // 这个公式很关键。这是求每个点对应的九宫格row[i][num] = true;col[j][num] = true;grid[k][num] = true;}}}}bool dfs(int i,int j){bool flag = false;if(i == 9) return true;if(map[i][j] != 0){if(j == 8){flag = dfs(i + 1, 0);}else{flag = dfs(i, j + 1);}if(flag) //在这回溯,但不改变map的值,只起到一个传递的作用return true;elsereturn false;}else{int k = 3 * (i / 3) + j / 3;for(int x = 1; x <= 9; x++){if(!row[i][x] && !col[j][x] && !grid[k][x]){map[i][j] = x;row[i][x] = true;col[j][x] = true;grid[k][x] = true;if(j == 8){flag = dfs(i + 1, 0);}else{flag = dfs(i, j + 1);}if(!flag) //这也是一个回溯{map[i][j] = 0;row[i][x] = false;col[j][x] = false;grid[k][x] = false;}else{return true;}}//if}//for}return false;}void output(){for(int i = 0; i < 9; i++){for(int j = 0; j < 9; j++){printf("%d", map[i][j]);}printf("\n");}}int main(){freopen("in.txt","r",stdin);scanf("%d", &n);while(n--){memset(row, false, sizeof(row));memset(col, false, sizeof(col));memset(grid, false, sizeof(grid));CreateMap();dfs(0, 0);output();}return 0;}
- poj_2676
- poj_2676
- poj_2676 Sudoku
- poj_2676 Sudoku(dfs)
- POJ_2676 数独解题报告
- POJ_2676:数独问题-DFS暴力搜索
- Eclipse:启动Eclipse打不开,一闪而过
- 小技巧:Mac下快速锁屏
- 修复Ubuntu 12.04 Grub 引导
- jQuery Ajax文件上传(php)
- JAVA经典编程50题
- poj_2676
- Python一天入门16:面向对象的编程3-继承
- 整理一些网页常用的tab选项卡效果
- GhostDoc使用与原始注释
- Python一天入门17:输入/输出-文件
- MFC程序显示主窗口的秘密
- 蓝桥杯2011 模拟 java 高职
- 赛马问题
- 开发板gec2440