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北京奥运会上,会将数独列为 ...
随机推荐
- NSThread那些事儿
NSThread 哎呀,它面向对象,再去看看苹果提供的API,对比一下Pthreads,简单明了,人生仿佛又充满了阳光和希望,我们先来一看一下系统提供给我们的API自然就知道怎么用了,来来来,我给你注 ...
- Java入门 手把手教你配置环境变量
很多人觉得配置Java开发的环境变量很麻烦,很容易忘记,时常被它搞得晕头转向.如果出现这样的情况,那么原因只有一个,你不了解为毛需要配置环境变量,不配置环境变量就不能开发了吗? 答案是:NO!,那么下 ...
- 【APUE】Chapter11 Threads
看完了APUE第三版的Chapter11 Threads,跟着书上的demo走了一遍,并且参考了这个blog(http://www.cnblogs.com/chuyuhuashi/p/4447817. ...
- IIS Express mime type 列表。
C:\Users\Administrator\Documents\IISExpress\config\applicationhost.config -------------------------- ...
- 第二阶段团队冲刺-seven
昨天: 合并程序(添加打印txt). 今天: 整体调试程序继续优化. 遇到的问题: 解决前两天的问题.
- 【转】Unity3D研究院之设置自动旋转屏幕默认旋转方向
http://www.xuanyusong.com/archives/2871 如下图所示,在处理屏幕默认旋转方向的时候可以在这里进行选择,上下左右一共是4个方向. 策划的需求是游戏采用横屏,但是要求 ...
- [转]mysql联合索引
mysql联合索引 命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https:/ ...
- Python中的单元测试模块Unittest快速入门
前言 为什么需要单元测试? 如果没有单元测试,我们会遇到这种情况:已有的健康运行的代码在经过改动之后,我们无法得知改动之后是否引入了Bug.如果有单元测试的话,只要单元测试全部通过,我们就可以保证没有 ...
- 如何修改root密码
默认情况下,每次登录ubuntu都会生成一个随机的root密码,如果想要修改, sudo passwd 然后输入密码,这个密码就作为root用户的密码
- BZOJ2599 [IOI2011]Race 【点分治】
题目 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 输入格式 第一行 两个整数 n, k 第二..n行 每行三个整 ...