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.把要补全的空格,放入数组,这样就不用遍历整个图寻找要填的空格了. ...
随机推荐
- struts2 参数注入 方法拦截器
web.xml: <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi=" ...
- linux基础命令:
linux基础命令: 显示 echo 输出我写的内容 ls 查看当前目录的文件 pwd 查看当前目录 ifconfig 查看网卡信息 grep 过滤 -v 取反 -n man 查看命令的帮助信息 md ...
- SQL 数据库事务 存储过程练习
数据库事务: 数据库事务(Database Transaction) 是指作为单个逻辑工作单元执行的一系列操作. 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源. ...
- rabbitMQ 常用命令
启动监控管理器:rabbitmq-plugins enable rabbitmq_management 关闭监控管理器:rabbitmq-plugins disable rabbitmq_manage ...
- vs2015安装出问题
win7系统需要更新serverpage1包,更新完就ok了,ie不用升级到ie10
- 10.9zuoye
public class fulei { public fulei() { System.out.println("欢迎使用海尔"); } public String Pinpai ...
- css position定位详解
position:static 默认方式: position:relative 相对定位,相对于原有位置进行移动,并且保留它在文件流中的占位: position:absolute 绝对定位,相对于最近 ...
- ios 处理WKContentView的crash
http://www.jianshu.com/p/7ef5814a871b 解决WKContentView没有isSecureTextEntry方法造成的crash 程序中有web页面,使用W ...
- 快速排序C++实现
#include<iostream> using namespace std;class quicksort{ public: int quicks(int *a,int low,int ...
- 【校招面试 之 C/C++】第28题 C++ 内存泄漏的检查
1.memwatch的使用 (1)首先去官网上下载源码: http://www.linkdata.se/sourcecode/memwatch/ 解压得到memwatch.c以及memwatch.h两 ...