本文链接: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. 通过广播关闭应用程序(每个Activity)和连续点击两次返回键关闭应用程序

    对于一个应用程序可能有很多个Activity,可能每个人并不想一个个的去关闭Activity,也有可能忘了,那怎么关闭所有的未关闭的Activity呢,其实有很多方法,但是我最喜欢的一种就是通过广播事 ...

  2. 《Cracking the Coding Interview》——第12章:测试——题目5·

    2014-04-25 00:41 题目:怎么测试一支笔?(Pen?您老说的是钢笔?) 解法:这种简约而不简单的题目,实在是面试官最喜欢,面试者最头疼的类型了.面试官可以只花三秒,以一种灰常高贵冷艳的语 ...

  3. CandyCrush 糖果传奇

    1.unity自带触发事件 unity的每一个Collider对象都有类似OnMouseDown.OnMouseOver等事件.此事件是存在于MonoBehaviour脚本里的,而MonoBehavi ...

  4. 上手Caffe(二)

    @author:oneBite本文简述如何在windows环境下,运行caffe的“hello world”例程体会适用caffe的流程:转换输入数据格式>在solver.prototxt中配置 ...

  5. php学习ing

    cmd运行,表示在本地d:/php/workspace下文件映射在127.0.0.1的8080端口下,-S -t不要忘记 php -S 127.0.0.1:8080 -t E:\class_manag ...

  6. php 数据库内容增删改查----增

    首先,建立一个主页面(crud.php) <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  7. # ML学习小笔记—Where does the error come from?

    关于本课程的相关资料http://speech.ee.ntu.edu.tw/~tlkagk/courses_ML17.html 错误来自哪里? error due to "bias" ...

  8. qemu中device和driver的区别 使用9p文件系统

    qemu配置中经常会出现-driver/-device的选项,可以理解成-driver是后端设备,即一个实际的物理的磁盘:device是把这块磁盘插入到虚机中的pci控制器中. 这样的话,虚机也能看到 ...

  9. Struts1 多个配置文件的实现

    在Struts 1.0中,我们只能在web.xml中为ActionServlet指定一个配置文件,这对于我们这些网上的教学例子来说当然没什么问题,但是在实际的应用开发过程中,可能会有些麻烦.因为许多开 ...

  10. C#中不用安装Oracle客户端连接Oracle数据库(转)

    原文地址:http://www.cnblogs.com/jiangguang/archive/2013/02/19/2916882.html 0.首先,从Oracle网站上下载对应版本的Oracle ...