数独问题的介绍及POJ 2676-Sudoku(dfs+剪枝)
知道是数独问题后犹豫了一下要不要做(好像很难的样纸==。),用dfs并剪枝,是一道挺规范的搜索题。
先介绍以下数独吧~
数独(Sudoku)是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格 的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。
有一种求解数独问题的方案是“候选数字法”,就是在待填充的格子中填写不会造成行重复、列重复、块重复的数字,有的时候存在多个这样的数字,那么我们可以随机选取一个,如果待填充的格子中填写任何一个数字都会造成某种重复的发生,则说明这个问题没有解,也就是这不是一个数独问题。
想要更加深入了解的同学可以点此链接:http://www.cnblogs.com/grenet/archive/2013/06/19/3138654.html
下面来说说POJ的这道题吧!
题目大意:
给你一个数独,让你填数:
1.每行的九个数字互不相同;
2.每列的九个数字各不相同;
3.被分成的3*3的小矩阵中的九个数字互不相同;
输出完成后的数表,若不能满足上述条件,则输出原图。
解题思路:
DFS。。失败了回溯~
从小优女神那里看到的存储方式(觉得很是方便呀!)
用三个数组进行标记每行、每列、每个子网格已用的数字,用于剪枝
bool row[10][10]; //row[i][x] 标记在第i行中数字x是否出现了
bool col[10][10]; //col[j][y] 标记在第j列中数字y是否出现了
bool small[10][10]; //small[k][x] 标记在第k个3*3子格中数字z是否出现了
row 和 col的标记比较好处理,关键是找出small子网格的序号与 行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
这样我们就能记录k个3*3子格中数字z是否出现了:
下面是我的代码:
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<vector>
#define inf 1<<25
#define LL long long
using namespace std;
int row[][];
int col[][];
int map[][];
int small[][];
int f(int x,int y)
{
return *((x-)/)+(y-)/+;
}
void init()
{
int i,j;
char ch;
memset(row,,sizeof(row));
memset(col,,sizeof(col));
memset(small,,sizeof(small));
for(i=; i<=; i++)
{
for(j=; j<=; j++)
{
scanf("%c",&ch);
map[i][j]=ch-'';
if(map[i][j])
{
int k;
k=f(i,j);
row[i][map[i][j]]=;
col[j][map[i][j]]=;
small[k][map[i][j]]=;
}
}
getchar();
}
}
int dfs(int x,int y)
{
if(x==)
return ;
int flag=;
if(map[x][y])
{
if(y==)
flag=dfs(x+,);
else
flag=dfs(x,y+);
if(flag)
return ;
else
return ;
}
else
{
int k=f(x,y);
for(int i=; i<=; i++)
if(!row[x][i] && !col[y][i] && !small[k][i])
{
map[x][y]=i;
row[x][i]=;
col[y][i]=;
small[k][i]=;
if(y==)
flag=dfs(x+,);
else
flag=dfs(x,y+);
if(!flag)
{
map[x][y]=;
row[x][i]=;
col[y][i]=;
small[k][i]=;
}
else
return ;
}
}
return ;
}
int main()
{
int t;
scanf("%d",&t);
getchar();
while(t--)
{
init();
dfs(,);
for(int i=; i<=; i++)
{
for(int j=; j<=; j++)
printf("%d",map[i][j]);
printf("\n");
}
}
return ;
}
数独问题的介绍及POJ 2676-Sudoku(dfs+剪枝)的更多相关文章
- ACM : POJ 2676 SudoKu DFS - 数独
SudoKu Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu POJ 2676 Descr ...
- poj 2676 Sudoku ( dfs )
dfs 用的还是不行啊,做题还是得看别人的博客!!! 题目:http://poj.org/problem?id=2676 题意:把一个9行9列的网格,再细分为9个3*3的子网格,要求每行.每列.每个子 ...
- 深搜+回溯 POJ 2676 Sudoku
POJ 2676 Sudoku Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17627 Accepted: 8538 ...
- POJ 2676 Sudoku (数独 DFS)
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14368 Accepted: 7102 Special Judg ...
- POJ 2676 - Sudoku - [蓝桥杯 数独][DFS]
题目链接:http://poj.org/problem?id=2676 Time Limit: 2000MS Memory Limit: 65536K Description Sudoku is a ...
- 搜索 --- 数独求解 POJ 2676 Sudoku
Sudoku Problem's Link: http://poj.org/problem?id=2676 Mean: 略 analyse: 记录所有空位置,判断当前空位置是否可以填某个数,然后直 ...
- 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 ...
- POJ 2676 Sudoku
Sudoku Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 12005 Accepted: 5984 Special ...
- POJ 2676 Sudoku(深搜)
Sudoku Time Limit : 4000/2000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total Submi ...
随机推荐
- 详解iOS7升级细节:引领视觉革命
下星期我们将看到的正式版将和WWDC上看到的大不相同.苹果六月份发布了全新版本的iOS操作系统——这是从2007年首次发布以来的最大的一次调整和改进.这次的改变招致许多批评.许多设计师在网站上晒出了他 ...
- LTP介绍
1.LTP介绍 LTP--linut test project ,ltp套件是由Linux Test Project所开发的一套系统測试套件.它基于系统资源的利用率统计开发了一个測试的组合,为系 ...
- BZOJ 2318: Spoj4060 game with probability Problem( 概率dp )
概率dp... http://blog.csdn.net/Vmurder/article/details/46467899 ( from : [辗转山河弋流歌 by 空灰冰魂] ) 这个讲得很好 , ...
- java--实例成员 & 静态成员
class run{ static String str1 = "静态变量"; String str2 = "非静态变量"; public static voi ...
- 09-IOSCore - 应用互动、UIImagePickerController
一.调用系统程序/服务 1. 应用互动数据权限 1) 跟自己本地数据交互 2) 跟网络服务器/云数据交互 3) 跟系统数据服务交互 4) 跟其它应用程序交互 2. 基础 URL 统一资源定位 一个特殊 ...
- 05-IOSCore - 单例模式、KVO
单例模式 是设计模式之一,使用频率高,让数据或对象在程序的各个地方都能访问,保持唯一 要素: 各个地方都能访问方法 + 静态消息 只要导入类 就能访问 保持唯一 1.在静态消息内限制对象的创建 2.外 ...
- 排行榜妙用——CSS计数器
碰到的坑 小伙伴你们是否有碰到以下的情况,排行榜前3名的样式不一样,你们是怎么处理的么?
- zookeeper 之znode 节点
<pre name="code" class="html">使用 ls 命令来查看当前 ZooKeeper 中所包含的内容: [zk: 10.77. ...
- win7系统远程连接其它计算机,并且向远程机传输文件
首先,打开开始菜单,在程序自带的 “附件“ 中找到 "远程桌面连接"并打开,出现远程桌面对话框: 其次,在对话框左下角点击“选项”,选择“本地资源对话框”,在本地设备和资源下点击“ ...
- 一步一步重写 CodeIgniter 框架 (1) —— url 如何映射到具体的方法
CodeIgniter 框架最显著的特征就是 MVC 模式,它的做法就是提取 url 中的'分段', 映射到某个类的某个方法,从而由该方法来输出最终显示的页面内容.那么我们第一课中就是实现一个这样的原 ...