本文链接: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. 剑指Offer - 九度1356 - 孩子们的游戏(圆圈中最后剩下的数)

    剑指Offer - 九度1356 - 孩子们的游戏(圆圈中最后剩下的数)2014-02-05 19:37 题目描述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.H ...

  2. chrome flash插件改为自动运行

    1.情景展示 国内网页视频播放大部分用的都是flash插件,每次都要将默认改为允许,才能正常播放         能不能让flash插件在所有的网站上都能自动运行呢? 2.解决方案 第一步:打开fla ...

  3. 自动化测试(二)如何用python写一个用户登陆功能

    需求信息: 写一个判断登录的程序: 输入: username password 最大错误次数是3次,输入3次都没有登录成功,提示错误次数达到上限 需要判断输入是否为空,什么也不输入,输入一个空格.n个 ...

  4. Vue_初识

    前端三大框架: vue:开发效率相当高了. angalar:适合做后台管理系统,入手容易,但是越往后会越难受. react:虚拟dom(渲染内存中存储的dom,经过操作后,才会去渲染浏览器的真实dom ...

  5. (转\整)UE4游戏优化 多人大地型游戏的优化(四)内存的优化

    施主分享随缘,评论随心,@author:白袍小道,当苦无妨 小道暗语: 1.因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了.标题格式大致都是(原or转) 二级目录 (标题 ...

  6. web知识清单

    声名随笔中的实例链接到另一个博客是我本人的另一个博客号 模块一:HTML 1.html是什么: hyperText markup language超文本标记语言 超文本:比文本更丰富的内容 所有的浏览 ...

  7. mssql发布订阅事项

    在发布订阅过程中遇到2个需求: 1.在原有的发布快照中增加发布内容,追加模式需要在追加的表中设计一个主键,要不然没有办法进行发布的,另外还得注意将这两个字段进行更改: select immediate ...

  8. 安卓自动化robotium工具简单使用(二)

    在学习安卓的这段时间里,刚好有个朋友有一个APP的应用需要开发. 我马上就动手开始做着试试,在完成开发的同时写了相应的自动化测试代码,使用的是robotium. 才接触安卓没几天,写的不太好,如果有好 ...

  9. c++ object model

    对一个结构体进行不断的封装后可以形成一个c++类,为此需要添加很多函数成员之类的代码,为此显示c++比c语言显得庞大并且迟缓,但是事实并不是这些 c++在布局和时间上的额外承担主要是由virtual引 ...

  10. 【bzoj1899】[Zjoi2004]Lunch 午餐 dp

    题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...