本文链接:http://i.cnblogs.com/EditPosts.aspx?postid=5398818

题意:

  给你一个 9*9 的矩阵,同一行相邻的两个元素用一个空格分开。其中1-9代表该位置的已经填好的数,问号(?)表示需要你填的数。输出这个数独的解,每组有且只有一个解。

思路:

  记录下空缺的地方,每个空缺的地方有 9 中状态,DFS + 剪枝处理其他的,用scanf进行输入,gets() TLE到死。。。。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std; const int MAXN = ;
int Gra[MAXN][MAXN];//存放 9 * 9 的大格局
int Ans[]; //存放 空缺的、要填数的 位置的 一种映射 (i - 1 ) * 9 + j
int rowLine[][]; //rowLine[ z = (i - 1) / 3 * 3 + (j - 1) / 3 ][k]表示 第 z(0 1 2 3 4 5 6 7 8) 个格子中 k 数字是否出现过(0 / 1)
int line[][]; // line[i][k] 表示 第 i 行 k 这个数字是否出现过
int row[][]; //row[j][k] 表示 第 j 列 k 这个数字是否出现过
int N; //要填数的格子的总数 int getX(int k) //根据存放空缺位置的数组的第k个数反推出坐标 X
{
return (Ans[k] - ) / + ;
}
int getY(int k) //根据存放空缺位置的数组的第k个数反推出坐标 Y
{
return Ans[k] % == ? : Ans[k] % ;
} void deal(int i, int j, int k, int num) //在 Gra(i, j)位置 放k(num = 1)/移走k(num = -1) 时需要维护用于标记是否重复的数组
{
line[i][ k ] += num; //维护行数组
row[j][ k ] += num; //维护列数组
rowLine[(i - ) / * + (j - ) / ][k] += num; //维护 标记 3 * 3 的数组
} int check(int k, int n) //判断在 第 n 个空缺的地方放置 k 是否合法
{
int x = getX(n);
int y = getY(n);
if(line[x][k] == ) return ; //同一行有重复的
if(row[y][k] == ) return ; //同一列有重复的
if(rowLine[ (x - ) / * + (y - ) / ][k] == ) return ; //同一个 3 * 3的方格子里有重复的
return ;
} void pf()
{
for(int i = ; i <= ; i++)
{
for(int j = ; j <= ; j++)
printf(j == ? "%d":" %d",Gra[i][j]);
cout <<endl;
}
} int flag;
void backtrack(int k)
{
if( k > N ){pf();flag = ;return;}
for(int i = ; i <= ; i++) //每一个 空缺的位置都有 9 种填法(状态)
{
int x = getX(k);int y = getY(k);
if(check(i, k)) //判断合法性
{
Gra[ x ][ y ] = i;
deal(x, y, i, ); //由于新加入的数 所以需要维护 标志的数组
backtrack( k + );
//if(flag )return;
deal(x, y, i, -); //恢复现场
Gra[ x ][ y ] = ;
}
}
} //初始化
void init()
{
N = ;
flag = ;
memset(Gra, -, sizeof(Gra));
memset(rowLine, , sizeof(rowLine));
memset(Ans, , sizeof(Ans));
memset(line, , sizeof(line));
memset(row, , sizeof(row));
} int main()
{ //freopen("in.txt", "r", stdin);
char s[];
int ln = ;
while(~scanf("%s",s))
{
if(ln++)printf("\n");
init();
if(s[] == '?'){Gra[][] = ; Ans[++N] = ;}
else{ Gra[][] = s[] - ; deal( , , Gra[][], );}
for(int i = ; i < ; i++)
{
for(int j = ; j < ; j++)
{
if(i == && j == )continue;
scanf("%s",s);
if(s[] == '?'){Gra[i + ][j + ] = ; Ans[++N] = i * + j + ;}
else{ Gra[i + ][j + ] = s[] - ; deal(i + , j + , Gra[i + ][j + ], );}
}
}
flag = ;
backtrack();
}
return ;
}

HDU 1426 Sudoku Killer (回溯 + 剪枝)的更多相关文章

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

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

  2. hdu 1426 Sudoku Killer (dfs)

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

  3. hdu 1426:Sudoku Killer(DFS深搜,进阶题目,求数独的解)

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

  4. hdu 1426 Sudoku Killer

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

  5. HDU 1426 Sudoku Killer(搜索)

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

  6. HDU 1426 Sudoku Killer【DFS 数独】

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

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

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

  8. HUD 1426 Sudoku Killer (DFS)

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

  9. P - Sudoku Killer HDU - 1426(dfs + map统计数据)

    P - Sudoku Killer HDU - 1426 自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会将数独列为 ...

随机推荐

  1. linux文件上传下载笔记(rz,sz,sftp,scp)命令

    软件(包)安装/卸载 yum -y install 包名(支持*) :自动选择y,全自动yum install 包名(支持*) :手动选择y or nyum remove 包名(不支持*)rpm -i ...

  2. 使用java去对比2个带数学公式的字符串

    首先大家看到这个题目,可能会不屑一顾,呵呵,是的,起初我也认为这是个很简单的任务,当任务拿到手里后,经过我作为程序员来讲已经磨炼的无比通透的大脑来讲发现这其实是个坑. 故事的起因是这样的,想开发一款给 ...

  3. vue.js中created方法作用

    这是它的一个生命周期钩子函数,就是一个vue实例被生成后调用这个函数.一个vue实例被生成后还要绑定到某个html元素上,之后还要进行编译,然后再插入到document中.每一个阶段都会有一个钩子函数 ...

  4. BigDecimal简单说

    1) 浮点数的舍弃规则: 假设小数点后保留两位 RoundingMode.CEILING:向正无穷大的方向舍入:  1.245 → 1.25   -1.245 → -1.24 RoundingMode ...

  5. python学习总结---面向对象2

    面向对象三大特点 - 封装:既是对数据结构的封装,有是处理数据的方法的封装. - 继承:强调的父子类的关系. - 多态:不同对象调用相同的方法,有不同的响应. 类的继承 - 相关概念 - 继承:父类的 ...

  6. 遍历列表,打印:我叫name,今年age岁,家住dizhi,电话phone(我是通过下标取键得到对应值,有哪位大神来个更简单的)

    lt = [ {'name':'小王', 'age':18, 'info':[('phone', '123'), ('dizhi', '广州')]}, {'name':'小芳', 'age':19, ...

  7. 孤荷凌寒自学python第六十一天在Fedora28版的linux系统上找搭建本地Mongodb数据服务

    孤荷凌寒自学python第六十一天在Fedora28版的linux系统上找搭建本地Mongodb数据服务 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第七天.成功在本地搭建 ...

  8. 转载:Android SQLite数据库版本升级原理解析

    Android使用SQLite数据库保存数据,那数据库版本升级是怎么回事呢,这里说一下. 一.软件v1.0 安装v1.0,假设v1.0版本只有一个account表,这时走继承SQLiteOpenHel ...

  9. 新浪微博 page应用 自适应高度设定 终于找到解决方法

    我做的是PAGE应用,无法自适应高度.找了好久解决方法. 用js 设置父窗口 iframe 也不好用,有的浏览器不兼容. 官方上说发是这样的: 应用动态高度自适应 Iframe高度:开发者可以使Ifr ...

  10. 第十四篇:JavaScript

    本篇内容 简介 使用 DOM 一. 简介 JavaScript 是世界上最流行的编程语言. 这门语言可用于 HTML 和 web,更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备. Ja ...