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. Linux平台Boost的编译方法

    本博客(http://blog.csdn.net/livelylittlefish)贴出作 者(三二一@小鱼)相关研究.学习内容所做的笔记,欢迎广大朋友指正! Linux平台Boost的编译方法 Bo ...

  2. 【APP接口开发】php获取body数据

    PHP获取接口数据: $postStr = file_get_contents("php://input");//因为很多都设置了register_globals禁止,不能用$GL ...

  3. Netty(七):流数据的传输处理

    Socket Buffer的缺陷 对于例如TCP/IP这种基于流的传输协议实现,接收到的数据会被存储在socket的接受缓冲区内.不幸的是,这种基于流的传输缓冲区并不是一个包队列,而是一个字节队列.这 ...

  4. php AES加密解密的例子

    一共有两个文件:AES.php(aes算法类文件)和aesDemo.php(应用实例文件) aesDemo.php:例子, <?php require_once('./AES.php'); // ...

  5. centos5.5 快速安装mysql

    安装MySQL. [root@sample ~]# yum -y install mysql-server ← 安装MySQL[root@sample ~]# yum -y install php-m ...

  6. 0x01 译文:Windows桌面应用Win32开发简介

    本节课将简单介绍下使用C++开发Windows桌面应用的一些基础知识 目录: 准备你的开发环境 Windows 代码规范 操作字符串 什么是一个Window? WinMain:程序的入口点 1. 准备 ...

  7. tcpdump常用参数说明

    (一).学习tcpdump的5个参数 初次使用tcpdump时,使用tcpdump -h命令可以看到它有数十个参数. 根据我们在运维工作中的经验,掌握tcpdump以下5个参数即可满足大部分的工作需要 ...

  8. makefile之override

    override指示符 通常在执行 make 时,如果通过命令行定义了一个变量,那么它将替代在 Makefile中出现的同名变量的定义. 就是说,对于一个在 Makefile 中使用常规方式(使用&q ...

  9. 每日英语:How to find the career of your dreams

    The fate described by Dostoyevsky is a nightmare we all hope to escape. But we're surrounded by nays ...

  10. Java 之进制转换

    //十进制转十六进制 import java.util.Scanner; public class Main{ public static void main(String[] args){ Scan ...