想了好久没想到好的解决办法,参考了 http://user.qzone.qq.com/289065406/blog/1303713313

大致题意:

九宫格问题,也有人叫数独问题

把一个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

 

又我在程序中使用的数组下标为 1~9,grid编号也为1~9

因此上面的关系式可变形为 3*((i-1)/3)+(j-1)/3+1=k

 

 

有了这个推导的关系式,问题的处理就变得非常简单了,直接DFS即可

//Memory Time
//216K 422MS #include<iostream>
using namespace std;
//纵x 行y 即x行y列
int map[10][10]; //九宫格 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是否出现了 //(这里说明的字母不代表下面程序中的变量) bool DFS(int x,int y)
{ //满足的条件是:找到最后一个 如果是true 那回溯上来都会是true 这是成立的情况 如果在中间出现false
//就要往前回溯 换个数字试试;
//成功的条件是
if(x==10)return true;//前面所有都满足了 已经没得找了
bool flag=false;
if(map[x][y]){
//if(x<9)DFS(x+1,y); //这样找的话会重复
//else if(y<9)DFS(x,y+1);
//所以我们一行一行找
if(y<9)
flag= DFS(x,y+1);
else flag=DFS(x+1,1);
return flag;//回溯 成功返回TRUE
}
else {
int k=3*((x-1)/3)+(y-1)/3+1; //k为第几个子方格
for(int i=1;i<=9;i++) //枚举数字1~9填空
{
if(row[x][i]==false&&col[y][i]==false&&grid[k][i]==false){
map[x][y]=i;
row[x][i]=true;
col[y][i]=true;
grid[k][i]=true;
//继续下找
if(y<9)
flag =DFS(x,y+1);
else flag=DFS(x+1,1);
if(flag==false){//不满足就原路返回
map[x][y]=0;
row[x][i]=false;
col[y][i]=false;
grid[k][i]=false;
}
else return true; } }
}
return false; //所有数字试过都不行的话
} int main()
{
int test;
int i,j;
char MAP[10][10];
cin>>test;
while(test--)
{
/*Initial*/ memset(row,false,sizeof(row));
memset(col,false,sizeof(col));
memset(grid,false,sizeof(grid)); /*Input*/
for(i=1;i<=9;i++)
for(j=1;j<=9;j++)
{
cin>>MAP[i][j]; //只能输入字符
map[i][j]=MAP[i][j]-'0';
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;
grid[k][ map[i][j] ]=true;
}
} /*Fill the Sudoku*/
DFS(1,1); for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
cout<<map[i][j];
cout<<endl;
}
}
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ2676-Sudoku(数独)的更多相关文章

  1. POJ2676 Sudoku [数独]

    好题,也非常有用,犯了几个错误 1.在枚举赋值的时候,思维有个错误:当当前的赋值不能填完这个数独,应该是继续下一个循环,而不是return false 终止枚举 2.Generic Programin ...

  2. poj2676 Sudoku(DFS)

    做了很久还是参考了别人的答案orz,其实也不难啊.我要开始学一下怎么写搜索了... 题目链接:poj2676 Sudoku 题解:暴力搜索,DFS每个空白格子所放数字. #include<cst ...

  3. POJ2676 – Sudoku(数独)—DFS

    Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24081   Accepted: 11242   Specia ...

  4. Sudoku 数独游戏

    #include<iostream> using namespace std; bool heng(int **sudo, int a, int b, int value) { bool ...

  5. POJ Sudoku 数独填数 DFS

    题目链接:Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18105   Accepted: 8772   Sp ...

  6. leetcode 37. Sudoku Solver 36. Valid Sudoku 数独问题

    三星机试也考了类似的题目,只不过是要针对给出的数独修改其中三个错误数字,总过10个测试用例只过了3个与世界500强无缘了 36. Valid Sudoku Determine if a Sudoku ...

  7. valid sudoku(数独)

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

  8. POJ 2676 Sudoku (数独 DFS)

      Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14368   Accepted: 7102   Special Judg ...

  9. POJ - 2676 Sudoku 数独游戏 dfs神奇的反搜

    Sudoku Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smalle ...

  10. 2015南阳CCPC H - Sudoku 数独

    H - Sudoku Description Yi Sima was one of the best counselors of Cao Cao. He likes to play a funny g ...

随机推荐

  1. sql 基本操作

    SQL基本操作   一数据类型1整数型 int2精确数值型 decimal(n,p)n为总位数,p为小数位数3浮点型 float4字符型char(n)n最大为4,varchar(n)5日期型datat ...

  2. spark-submit工具参数说明

    执行时需要传入的参数说明 Usage: spark-submit [options] <app jar | python file> [app options] 参数名称 含义 --mas ...

  3. 使用MySQL数据库

    登录到MySQL 当 MySQL 服务已经运行时, 我们可以通过MySQL自带的客户端工具登录到MySQL数据库中, 首先打开命令提示符, 输入以下格式的命名: mysql -h 主机名 -u 用户名 ...

  4. php 安装pdo_mysql 扩展

    如果pdo在linux下出现exception 'PDOException' with message 'could not find driver'则问题是php编译时少加--with-pdo-my ...

  5. tp框架集成支付宝,中转页变成gbk编码

    tp框架中集成支付宝的功能,将支付宝的demo例子存在到下图位置\Extend\Vendor\Alipay 生成支付订单 /** * 支付订单 */ public function pay() { h ...

  6. 【积硅计划】html标签

    一.基础     在html中,标签通常是由开始标签和结束标签组成,开始标签用<标签名>,结束标签用</标签名>      元素是指包括开始标签和结束标签在内的整体,内容是指出 ...

  7. jQuery ajax Load关闭缓存的方法

    [导读] 在jQuery ajax Load关闭缓存的方法很简单,我们只要在$ ajaxSetup中把cache: false就楞以了,当然我们还可以使用一个随机参数来实例了.简单介绍load(url ...

  8. Laravel 5 基础(十二)- 认证

    Laravel 出厂已经带有了用户认证系统,我们来看一下 routes.php,如果删除了,添加上: Route::controllers([ 'auth' => 'Auth\AuthContr ...

  9. 国际制造执行系统(MES)应用与发展

    某些专家认为,当今制造业的生存三要素是信息技术(IT).供应链管理(SCM)和成批制造技术.使用信息技术就是由依赖人工的作业方式转变为作业的快速化.高效化,大量减少人工介入,降低生产经营成本:供应链管 ...

  10. STM32F0xx_SPI读写(Flash)配置详细过程

    Ⅰ.概述 关于SPI(Serial Peripheral Interface)串行外设接口可以说是单片机或者嵌入式软件开发人员必须掌握的一项通信方式,就是你在面试相关工作的时候都可能会问及这个问题.在 ...