POJ2676 – Sudoku(数独)—DFS
Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions: 24081 | Accepted: 11242 | Special Judge |
Description

Input
Output
Sample Input
1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107
Sample Output
143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127 题意:就是普通的数独游戏,给出了初始状态的九宫格,让你打印出任意一种解法。
思路:这题用DFS来写。我们运用三个数组进行标记,从而得知每个格子可以放那些数,不可以放哪些数,然后dfs枚举即可。三个标记数组分别为line[][],column[][],block[][],
line:标记每一行哪些数已经被用了,哪些没被用;
column:标记每一列哪些数已经被用了,哪些没被用;
block:标记每一个3*3格子中哪些数被用过,哪些没被用;(判断某个格子为第几个块:3*3的块总共有三行和三列,假设格子索引从1-9,某个格子为第i行,第j列,可以知道它是(i-1)/3行的块,而且是(j-1)/3+1列的列,所以可以知道某个格子为第(i-1)/3*3+(j-1)/3+1块)
然后从第一个需要填数的格子开始,枚举1-9中可以填的所有数,然后将选中的数标记,继续下一个格子,若到达某个格子无数可选,则回溯。
具体看代码,最近在学Java,所以代码是用java写的,但语法基本和C++相同,所以不会java也能看懂。 代码:
import java.util.Scanner; public class Main {
static boolean line[][]; //标记行的数组,一维的数字表示第几行,二维的数字表示这一行的哪一个数
static boolean column[][]; //标记列的数组
static boolean block[][]; //标记块的数组 public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt(); //输入t
while(t-- > 0)
{
line = new boolean[15][15]; //数组初始化
column = new boolean[15][15];
block = new boolean[15][15]; int map[][] = new int[15][15];
int all = 0; //all用来统计有多少个格子需要填数
for(int i=1; i<10; ++i) {
String s = in.next(); //输入字符串 for(int j=1; j<10; ++j) {
map[i][j] = s.charAt(j-1) - '0'; //将字符串转化为数字存入数组
if(map[i][j] == 0) all++; //统计 line[i][ map[i][j] ] = true; //标记每一个已经出现的数
column[j][ map[i][j] ] = true;
int xx = (i-1)/3*3 + (j-1)/3 + 1; //计算这个格子在第几个3*3的块中
block[xx][ map[i][j] ] = true;
}
} outer:for(int i=1; i<10; ++i) //找到第一个需要填的格子
for(int j=1; j<10; ++j) {
if(map[i][j] == 0)
{
DFS(i,j,all,map);
break outer; //跳出到循环外
}
} for(int i=1; i<10; ++i)
{
for(int j=1; j<10; ++j)
{
System.out.print(map[i][j]);
}
System.out.println();
}
}
in.close();
} static boolean DFS(int x,int y,int all,int[][] map) { if(all == 0) { //如果所有的格子都被填满,返回true
return true;
} int x1=0,y1=0;
outer:for(int i=x; i<10; ++i) //找到这个格子之后需要填数的第一个格子
for(int j=1; j<10; ++j)
{
if(i==x && j==y) continue; //跳过目前这个格子
if(map[i][j] == 0)
{
x1 = i;
y1 = j;
break outer;
}
} int xx = (x-1)/3*3 + (y-1)/3 + 1; //计算这个格子为第几个块
for(int k=1; k<10; ++k) {
if(!line[x][k] && !column[y][k] && !block[xx][k] ) //若这个数未被标记,表示可选
{
map[x][y] = k; //在这个格子存储这个数
line[x][k] = true; //将这个数标记
column[y][k] = true;
block[xx][k] = true; if(DFS(x1,y1,all-1,map)) //搜索下一个需要填数的格子
return true; line[x][k] = false; //能运行到这里,说明填数失败,所以回溯
column[y][k] = false;
block[xx][k] = false;
}
}
map[x][y] = 0; //若没有一个数满足要求,则回到上一个数,且要把这个数变回0;
return false;
}
}
POJ2676 – Sudoku(数独)—DFS的更多相关文章
- poj2676 Sudoku(DFS)
做了很久还是参考了别人的答案orz,其实也不难啊.我要开始学一下怎么写搜索了... 题目链接:poj2676 Sudoku 题解:暴力搜索,DFS每个空白格子所放数字. #include<cst ...
- POJ 2676 Sudoku (数独 DFS)
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14368 Accepted: 7102 Special Judg ...
- POJ2676 Sudoku [数独]
好题,也非常有用,犯了几个错误 1.在枚举赋值的时候,思维有个错误:当当前的赋值不能填完这个数独,应该是继续下一个循环,而不是return false 终止枚举 2.Generic Programin ...
- hdu 1426 Sudoku Killer (dfs)
Sudoku Killer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 【POJ - 2676】Sudoku(数独 dfs+回溯)
-->Sudoku 直接中文 Descriptions: Sudoku对数独非常感兴趣,今天他在书上看到了几道数独题: 给定一个由3*3的方块分割而成的9*9的表格(如图),其中一些表格填有1- ...
- POJ Sudoku 数独填数 DFS
题目链接:Sudoku Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18105 Accepted: 8772 Sp ...
- POJ 2676 - Sudoku - [蓝桥杯 数独][DFS]
题目链接:http://poj.org/problem?id=2676 Time Limit: 2000MS Memory Limit: 65536K Description Sudoku is a ...
- 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 ...
- POJ2676 Sudoku(dfs)
题目链接. 题目大意: 就是数独游戏.横竖,每一个9宫方块,必须有1~9,且不重复. 分析: 直接DFS.一开始在原图上搜,会TLE.把要补全的空格,放入数组,这样就不用遍历整个图寻找要填的空格了. ...
随机推荐
- 解决PL/SQL导出cvs文件中文显示乱码
方法 1 导出csv格式文件 新建excel文件 比如 a.xls excel软件打开 选择菜单数据 -导入外部数据 unicode默认下一步 选择 逗号分隔符 点击确定导入完成 方法 2 导出成h ...
- CGBitmapContextCreate函数参数详解 以及在 ios7下变化
函数原型: CGContextRef CGBitmapContextCreate ( void *data, size_t width, size_t height, size_t ...
- 获得Variant类型
function GetVariantType(const v: variant): string; begin case TVarData(v).vType of varEmpty: r ...
- 【Java】JVM(一)、Java内存区域
一.程序计数器(Program Counter Register) 当前执行字节码的行号指示器,可以通过修改该计数器的值来实现字节码指令(分支,循环,跳转等), 每个线程都都有一个程序计数器, 属于线 ...
- Python sum() 函数
Python sum() 函数 Python 内置函数 描述 sum() 方法对系列进行求和计算. 语法 以下是 sum() 方法的语法: sum(iterable[, start]) 参数 ite ...
- Web服务技术协议:REST与SOAP
Web服务技术就有SOAP(Simple Object Access Protocol,简单对象访问协议)和REST(Representational State Transfer,表示性状态转移) ...
- ECMAScript6新特性之String API
填充到指定长度,默认使用空格填充. 一 左填充 var arr = []; for(var i=0;i<20;i++){ var str = (i+'').padStart(2,'0'); ar ...
- N皇后问题12 · N-Queens
[抄题]: n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击. 给定一个整数n,返回所有不同的n皇后问题的解决方案. 每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分 ...
- [leetcode]496. Next Greater Element I下一个较大元素
You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...
- 35-面试:如何找出字符串的字典序全排列的第N种
http://www.cnblogs.com/byrhuangqiang/p/3994499.html