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;}



原创粉丝点击