Sudoku Killer

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3723    Accepted Submission(s): 1170

Problem Description
自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视。
据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品———HDU免费七日游外加lcy亲笔签名以及同hdu acm team合影留念的机会。
所以全球人民前仆后继,为了奖品日夜训练茶饭不思。当然也包括初学者linle,不过他太笨了又没有多少耐性,只能做做最最基本的数独题,不过他还是想得到那些奖品,你能帮帮他吗?你只要把答案告诉他就可以,不用教他是怎么做的。

数独游戏的规则是这样的:在一个9x9的方格中,你需要把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证,空格中用粗线划分成9个3x3的方格也同时包含1-9这九个数字。比如有这样一个题,大家可以仔细观察一下,在这里面每行、每列,以及每个3x3的方格都包含1-9这九个数字。

例题:

答案:

 
Input
本题包含多组测试,每组之间由一个空行隔开。每组测试会给你一个 9*9 的矩阵,同一行相邻的两个元素用一个空格分开。其中1-9代表该位置的已经填好的数,问号(?)表示需要你填的数。
 
Output
对于每组测试,请输出它的解,同一行相邻的两个数用一个空格分开。两组解之间要一个空行。
对于每组测试数据保证它有且只有一个解。
 
Sample Input
   ?  ?
? ? ?
? ?
? ?
? ? ? ?
? ? ?
? ?
? ?
? ? ?
Sample Output

 
Author
linle
 
Source
 
Recommend
LL   |   We have carefully selected several similar problems for you:  1258 1045 2614 1067 1312 

 
  DFS搜索,进阶题目
  题意是给你多个数独题目,让你输出它们的答案。
  思路是递归确定每一个‘?’的位置的值,直到所有‘?’都被确定。先将原字符数组转换为整型数组,‘?’由数字0代替,然后每一次层递归找到第一个0的位置,如果找到了,找出当前位置所有可以放置的数字,依次尝试,每次假设把这个数放在当前位置,然后再确认下一个0位置的数字,直到数组中找不到0,即是正确结果(递归出口)。
  注意输入格式,要求输入的每组数据之间有一个空行,可以先单独输入第一组数据,后面的数据都是先读取空行,再读取数据。
  题目给的测试数据很弱,献上一组我的测试数据,如果你总是WA可以试试:
?  ?  ?  ? ?
? ? ? ? ?
? ? ? ? ?
? ? ? ?
? ? ? ? ? ?
? ? ? ? ?
? ? ? ? ?
? ? ? ? ?
? ? ? ? ?

  答案


  注意如果这一步的所有情况都判定失败,返回上一层递归的时候不要忘了将当前位置还原为“?”的状态,否则会影响以后的递归。

  代码量比别人长了一些,速度也达到了400MS左右,但好在关键地方都做了注释,代码还算好懂,看官们有改进意见可以跟我提。

  不费话了,上代码

 #include <stdio.h>
#include <iostream>
using namespace std;
void putoutint(int b[][]) //输出整型二维数组
{
int i,j;
for(i=;i<;i++){
for(j=;j<;j++)
if(j!=)
cout<<b[i][j]<<' ';
else
cout<<b[i][j];
cout<<endl;
}
}
void char2int(char a[][],int b[][]) //字符二维数组向整型二维数组转换
{
int i,j;
for(i=;i<;i++)
for(j=;j<;j++)
if(a[i][j]=='?')
b[i][j/] = ;
else if(''<=a[i][j] && a[i][j]<='')
b[i][j/] = a[i][j]-'';
}
bool judge(int curx,int cury,int num,const int b[][])
{
int i,j;
//查找一横行
for(i=;i<;i++) //将这一行出现的数字全部设为不可填
if(i!=cury && b[curx][i]==num)
return true;
//查找一竖列
for(i=;i<;i++) //将这一行出现的数字全部设为不可填
if(i!=curx && b[i][cury]==num)
return true;
//查找当前九宫格
int x,y;
x = curx/*;
y = cury/*;
for(i=;i<;i++)
for(j=;j<;j++)
if(x+i!=curx && y+j!=cury && b[x+i][y+j]==num)
return true;
return false;
}
bool dfs(int b[][])
{
//找到当前第一个'?'位置。如果没有找到,表示所有位置都已填上,即为正确结果,递归结束
int i,j;
for(i=;i<;i++)
for(j=;j<;j++)
if(b[i][j]==) //找'?'的位置
goto label;
label:
if(i>= && j>=) //找到正确结果了,递归结束
return true;
//记录坐标
int curx = i,cury = j;
//确定该位置的可以填的数字
bool temp[]; //记录哪些数字可以填
int num=; //记录当前位置可以填的数字的个数
for(i=;i<=;i++)
if(judge(curx,cury,i,b)) //判断这个位置可不可以放这个数字
temp[i] = false;
else {
temp[i] = true;
num++;
}
if(num==)
return false;
//确定下一个位置
for(i=;i<=;i++)
if(temp[i]){
//这个数在这个位置可以填
if(judge(curx,cury,i,b))
continue;
b[curx][cury] = i;
if(dfs(b))
return true;
}
b[curx][cury] = ; //这句千万别忘了写,就是这一步不能走的记得还原为0
return false;
}
int main()
{
char a[][];
int b[][];
int i;
for(i=;i<;i++)
cin.getline(a[i],,'\n');
char2int(a,b); //char数组转换为int数组
if(dfs(b)) //产生结果
putoutint(b); //输出数组内容 while(cin.getline(a[],,'\n')){ //读取空行,或者到文件尾
cout<<endl;
char a[][];
int b[][];
int i;
for(i=;i<;i++)
cin.getline(a[i],,'\n');
char2int(a,b); //char数组转换为int数组
if(dfs(b)) //产生结果
putoutint(b); //输出数组内容
}
return ;
}

Freecode : www.cnblogs.com/yym2013

hdu 1426:Sudoku Killer(DFS深搜,进阶题目,求数独的解)的更多相关文章

  1. hdu 1426 Sudoku Killer (dfs)

    Sudoku Killer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  2. HDU 1426 Sudoku Killer(dfs 解数独)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1426 Sudoku Killer Time Limit: 2000/1000 MS (Java/Oth ...

  3. HDU 1426 Sudoku Killer (回溯 + 剪枝)

    本文链接:http://i.cnblogs.com/EditPosts.aspx?postid=5398818 题意: 给你一个 9*9 的矩阵,同一行相邻的两个元素用一个空格分开.其中1-9代表该位 ...

  4. HDU 1426 Sudoku Killer【DFS 数独】

    自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品— ...

  5. hdu 1426 Sudoku Killer

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1426 #include<stdio.h> #include<math.h> #in ...

  6. HDU 1426 Sudoku Killer(搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1426 题意很明确,让你解一个9*9的数独. DFS即可. #include <cstdio> ...

  7. hdu 1426 Sudoku Killer ( Dancing Link 精确覆盖 )

    利用 Dancing Link 来解数独 详细的能够看    lrj 的训练指南 和 < Dancing Links 在搜索中的应用 >这篇论文 Dancing Link 来求解数独 , ...

  8. HUD 1426 Sudoku Killer (DFS)

    链接 : Here! 思路 : 记录下所有 "?" , 出现的位置, 然后 $DFS$ 一下, 对于每个位置来说都可以填充 $9$ 种数值, 然后对于判断填充是否合法需要三个标记数 ...

  9. CodeM美团点评编程大赛初赛B轮 黑白树【DFS深搜+暴力】

    [编程题] 黑白树 时间限制:1秒 空间限制:32768K 一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1.树上每个节点i对应一个值k[i].每个点都有一个颜色,初始的时候所有点都是白色 ...

随机推荐

  1. jsp基本语法总结

    一,用jsp脚本元素调用java代码 1,jsp表达式的应用 jsp表达式将值直接插入到输出中: <%= Java Expression %>  代表一个值 隐式对象,在使用jsp表达式的 ...

  2. 微信小程序项目实战之豆瓣天气

    概述 微信小程序项目实战之豆瓣天气 详细 代码下载:http://www.demodashi.com/demo/10943.html 一.准备工作 1.注册微信小程序 2.在小程序设置中设置reque ...

  3. Java 的抽象特性:抽象类与接口深度解析

    要点: 抽象类 接口 抽象类与接口的差别 一. 抽象 对于面向对象编程来说,抽象是它的四大特征之中的一个. 在Java中,能够通过两种形式来体现OOP的抽象:接口和抽象类. 接口和抽象类为我们提供了一 ...

  4. 【Redis】redis开机自启动、设置守护进程、密码设置、访问权限控制等安全设置(redis默认端口6379)

    一.redis设置开机自启动:centOS: 1.修改redis.conf中daemonize为yes,确保守护进程开启,也就是在后台可以运行. (守护进程:孤儿进程:独立于终端而存在的进程,不会因为 ...

  5. (一)struts2入门——登陆验证熟悉struts2部署

    0.了解 Struts(支柱.支干)是什么? Struts是流行和成熟的基于MVC设计模式的Web应用程序框架.使用它能帮助我们减少在运用MVC设计模型来开发Web应用时间. 为什么2.1.3之后用S ...

  6. iOS开发-多线程编程技术(Thread、Cocoa operations、GCD)

    简介 在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了.有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行.比如:前端和后台作交互.大任务(需要耗费一定的时间 ...

  7. maven打包到本地仓库里面

    mvn install:install-file -Dfile=D:/你的包名  -DgroupId=com.sdk4j -DartifactId=sdk4j -Dversion=1.0 -Dpack ...

  8. C++:模板友元

    模板友元函数在类内声明类外定义时都必须加模板前缀,另外模板要写在一个文件内 // generates undefined error for the operator<< function ...

  9. C#:复选框操作类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  10. linux 下安装 jdk tomcat 并配置

    linux下安装TOMCAT与JDK 第1步:新建boss用户,username:boss,password:boss 第2步:将安装用户路径设置成/app/boss [root@localhost] ...