HDU 1426 Sudoku Killer (回溯 + 剪枝)
本文链接: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 (回溯 + 剪枝)的更多相关文章
- HDU 1426 Sudoku Killer(dfs 解数独)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1426 Sudoku Killer Time Limit: 2000/1000 MS (Java/Oth ...
- hdu 1426 Sudoku Killer (dfs)
Sudoku Killer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- hdu 1426:Sudoku Killer(DFS深搜,进阶题目,求数独的解)
Sudoku Killer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- hdu 1426 Sudoku Killer
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1426 #include<stdio.h> #include<math.h> #in ...
- HDU 1426 Sudoku Killer(搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1426 题意很明确,让你解一个9*9的数独. DFS即可. #include <cstdio> ...
- HDU 1426 Sudoku Killer【DFS 数独】
自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品— ...
- hdu 1426 Sudoku Killer ( Dancing Link 精确覆盖 )
利用 Dancing Link 来解数独 详细的能够看 lrj 的训练指南 和 < Dancing Links 在搜索中的应用 >这篇论文 Dancing Link 来求解数独 , ...
- HUD 1426 Sudoku Killer (DFS)
链接 : Here! 思路 : 记录下所有 "?" , 出现的位置, 然后 $DFS$ 一下, 对于每个位置来说都可以填充 $9$ 种数值, 然后对于判断填充是否合法需要三个标记数 ...
- P - Sudoku Killer HDU - 1426(dfs + map统计数据)
P - Sudoku Killer HDU - 1426 自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会将数独列为 ...
随机推荐
- 自动化测试(三)如何用python写一个函数,这个函数的功能是,传入一个数字,产生N条邮箱,产生的邮箱不能重复。
写一个函数,这个函数的功能是,传入一个数字,产生N条邮箱,产生的邮箱不能重复.邮箱前面的长度是6-12之间,产生的邮箱必须包含大写字母.小写字母.数字和特殊字符 和上一期一样 代码中间有段比较混沌 有 ...
- Django学习笔记(二):使用Template让HTML、CSS参与网页建立
Django学习笔记(二):使用Template让HTML.CSS参与网页建立 通过本文章实现: 了解Django中Template的使用 让HTML.CSS等参与网页建立 利用静态文件应用网页样式 ...
- JS——BOM、DOM
BOM.DOM BOM window对象 history对象 location对象 screen对象 DOM DOM对HTML元素访问操作 HTML DOM树 DOM 节点 DOM访问HTML元素 D ...
- Python全栈工程师(数值类型、运算符)
ParisGabriel Python 入门基础 python的应用领域: 1.系统运维 2.网络编程(如:网络爬虫,搜索引擎,服务器编程) 3.科学计算 4.航空领域(如:卫星, ...
- pycharm安装scipy,安装失败
在pycharm中安装很长时间后,还是失败. 在命令行中尝试,使用python3. 命令:python3 -m pip install scipy. 发现下载速度很慢,只有十几k每秒,但scipy包有 ...
- 【多线程学习(1)】创建java多线程
1)java多线程的创建方式有三种: 1.继承Thread类 2.实现Runnable接口 3.实现Callable接口 第一种: //继承Thread类 class ExtendsThread ex ...
- ZOJ 3544 / HDU 4056 Draw a Mess( 并查集好题 )
方法参见:http://blog.acmol.com/?p=751 从最后一个线段开始倒着处理(因为之后的线段不会被它之前的线段覆盖),把这条线段所覆盖的所有线段编号合并到一个集合里,并以最左边线段编 ...
- Java性能监控之Java程序执行解析
大家好,最近接触javassist技术,研究过程中对Java程序执行过程进行了一系列探索,弄清楚了几个盲区(仅针对个人而言),现将经验与大家分享. 1.编码->.java 通常指写代码的过程,最 ...
- 【bzoj5055】膜法师 离散化+树状数组
题目描述 给定一个序列$a$,求满足$i<j<k$且$a_i<a_j<a_k$的三元组$(i,j,k)$的个数. 输入 第一行1个数 n 第二行n个数 a_i 输出 一个数,表 ...
- CSU 2031
2031: Barareh on Fire Submit Page Summary Time Limit: 3 Sec Memory Limit: 512 Mb Submitt ...