【POJ2676】Sudoku
本题知识点:深度优先搜索 + 回溯
问题就是要让我们解决一个数独问题。如果你懂得怎么玩数独的话,那就很自然想到用暴力搜索去做题。(比如我就不会,所以先WA了一发quq)
数独符合三个条件
- 同行里只有 1 ~ 9 这9个数字
- 同列里只有 1 ~ 9 这9个数字
- 在这9x9的方阵里有9个3x3的小方阵,每个小方阵里的9个数也只能是 1 ~ 9
注意,这每行每列每小方阵的9个数各都是1个
所以,我用了3个bool数组去存他们的状态
数据很小
2s我跑了700多ms就过了
详细可见代码
// POJ 2676
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int T, tot;
bool ok;
bool row[10][10]; // 行 i,j 表示第 i 行上的 j 已填
bool col[10][10]; // 列 i,j 表示第 i 列上的 j 已填
bool kuang[10][10][10]; // 小框里 a,b 表示在哪个小框里 i,j 表示小框里的数
char sudoku[10][10];
void build(){
// 注意要初始化
tot = 0; ok = false;
memset(row, false, sizeof(row));
memset(col, false, sizeof(col));
memset(kuang, false, sizeof(kuang));
for(int i = 1; i <= 9; i++) scanf("%s", sudoku[i] + 1);
for(int i = 1; i <= 9; i++) // 行
for(int j = 1; j <= 9; j++) // 列
if(sudoku[i][j] != '0'){
row[i][ sudoku[i][j] - '0' ] = true;
col[j][ sudoku[i][j] - '0' ] = true;
// 一个9x9的格子里有9个3x3的小格子,向上取整就可以找到小格子的位置啦(向下取整也可以,不过向下取整这里的3是1,不好处理,于是我用向上取整)
int a = ceil(i / 3.0), b = ceil(j / 3.0);
kuang[a][b][ sudoku[i][j] - '0' ] = true;
}
else tot++;
}
void dfs(int h, int w, int cnt){ // cnt 记录当前还有多少个格子未填
// 注意此尾都要加上 return
if(cnt == 0){ ok = true; return ; } // 都填完了,返回
if(w == 10) { dfs(h + 1, 1, cnt); return ; } // 该行填完了,进行下一行
if(sudoku[h][w] != '0') { dfs(h, w + 1, cnt); return ; } // 该元素不是空的,继续进行搜索
if(h == 10) return ; // 已经都搜索完 返回
int a = ceil(h / 3.0); // 9个小框的行
int b = ceil(w / 3.0); // 9个小框的列
// 对于位置为'0'的格子进行填数
for(int i = 1; i <= 9; i++){ // 该格子上的数字遍历数字
if(!row[h][i] && !col[w][i] && !kuang[a][b][i]){
// 更新状态
sudoku[h][w] = i + '0';
row[h][i] = true; col[w][i] = true; kuang[a][b][i] = true;
dfs(h, w + 1, cnt - 1); // 未填的格子减 1
if(ok) return ;
// 回溯状态
row[h][i] = false; col[w][i] = false; kuang[a][b][i] = false;
sudoku[h][w] = '0';
}
}
}
int main()
{
scanf("%d", &T);
while(T--){
build();
// 找到第一个没有填的格子
for(int i = 1; i <= 9; i++){
bool out = false;
for(int j = 1; j <= 9; j++){
if(sudoku[i][j] == '0'){
// printf("i:%d j:%d\n", i, j);
dfs(i, j, tot);
out = true;
break;
}
}
if(out) break;
}
// printf("tot:%d\n", tot);
// cout << endl;
for(int i = 1; i <= 9; i++)
printf("%s\n", sudoku[i] + 1);
}
return 0;
}
【POJ2676】Sudoku的更多相关文章
- 【POJ2676】sudoku 搜索
按照每一行每一列去填数,当填到每一行的第9列时,开始填下一行. 代码如下: #include <cstdio> #include <algorithm> #include &l ...
- 【leetcode】Sudoku Solver
Sudoku Solver Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are i ...
- 【UVA1309】Sudoku(DLX)
点此看题面 大致题意: 让你填完整一个\(16*16\)的数独. 解题思路 我们知道,数独问题显然可以用\(DLX\)解决. 考虑对于一个数独,它要满足的要求为:每个位置都必须有数,每一行都必须有全部 ...
- 【POJ3074】Sudoku DLX(Dancing Links)
数独就要DLX,不然不乐意. 数独的DLX构造:9*9个点每一个点有9种选择,这构成了DLX的729行,每行.列.阵有限制,均为9行(/列/阵),然后每行(/列/阵)都有九种数的情况.于是就有了3*9 ...
- 【LeetCode】哈希表 hash_table(共88题)
[1]Two Sum (2018年11月9日,k-sum专题,算法群衍生题) 给了一个数组 nums, 和一个 target 数字,要求返回一个下标的 pair, 使得这两个元素相加等于 target ...
- 【LeetCode】回溯法 backtracking(共39题)
[10]Regular Expression Matching [17]Letter Combinations of a Phone Number [22]Generate Parentheses ( ...
- 【LeetCode】36. Valid Sudoku 解题报告(Python)
[LeetCode]36. Valid Sudoku 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址 ...
- 【POJ 3076】 Sudoku
[题目链接] http://poj.org/problem?id=3076 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 [代码] #include <algorit ...
- 【POJ 3074】 Sudoku
[题目链接] http://poj.org/problem?id=3074 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 转化方法如下 : 我们知道,在一个数独中 : 1. ...
随机推荐
- c++关于IOCP(完成端口)的服务器开发
本文转载,以便更好的学习C++的服务器开发 1.对IOCP的理解,转载地址 2.在C++中对IOCP的实现,转载地址 注:其实在.net中 ,Socket的服务器开发中,SocketAsyncEven ...
- 女性长期没有"恩爱",会出现这4个后果?提醒:频率最好能在这个数
一直以来,很多人认为:男性性欲比女性强! 其实:因人而异! 但不管怎么说,“性”话题在如今社会中已经不再成为隐晦谈资. 越来越多的人,可以把此话题拿到桌面上各抒己见. 总归,“性”是我们探索自我的一种 ...
- JavaScript 之 事件(详解)
一.注册事件的三种方式 1.直接事件方式 语法格式: 变量名.on事件名 = function() {} 注意:这种方式无法给同一对象的同一事件注册多个事件处理函数 2.addEventListene ...
- 英语gzibeads天珠gzibeads单词
天珠英语是gZiBeads,藏语叫(si , 斯)汉语译为“斯”或“瑟”,又称“天降石”.在<藏汉大辞典>里天珠的解释为:“亚玛瑙,猫睛石,一种宝石,俗称九眼珠.入药能治脑溢血”.最早的天 ...
- RxJS——调度器(Scheduler)
调度器 什么是调度器?调度器是当开始订阅时,控制通知推送的.它由三个部分组成. 调度是数据结构.它知道怎样在优先级或其他标准去存储和排队运行的任务 调度器是一个执行上下文.它表示任务在何时何地执行(例 ...
- 你遇到过哪些原因造成MySQL异步复制延迟?
master上多为并发事务,salve上则多为单线程回放(MySQL 5.7起,支持真正的并行回放,有所缓解) 异步复制,本来就是有一定延迟的(否则也不叫做异步了,介意的话可以改成半同步复制) sla ...
- 【VNCserver】Centos7.4安装VNC连接华为云或亚马逊云
1.1 文档背景 CentOS 7 / RHEL 7部署图形化界面 安装VNCserver实现linux系统云主机桌面化,通过普通用户实现桌面化操作 2. Vncserver服务端部署 2.1 安装 ...
- mklink 文件夹链接 windows系统
MS文档 https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/mklink 命令参数 mkl ...
- AtCoder Beginner Contest 136
AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...
- httprunner学习24-sign签名验证
前言 一般公司对外的接口都会用到sign签名,对不同的客户提供不同的apikey ,这样可以提高接口请求的安全性,避免被人抓包后乱请求. sign签名是一种很常见的方式 关于sign签名的可以参考前面 ...