DFS剪枝——poj3074数独
题目连接
Description
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
. 2 7 3 8 . . 1 .
. 1 . . . 6 7 3 5
. . . . . . . 2 9
3 . 5 6 9 2 . 8 .
. . . . . . . . .
. 6 . 1 7 4 5 . 3
6 4 . . . . . . .
9 5 1 8 . . . 7 .
. 8 . . 6 5 3 4 .
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.
Input
The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.
Output
For each test case, print a line representing the completed Sudoku puzzle.
Sample Input
.2738…1…1…6735…293.5692.8…6.1745.364…9518…7…8…6534.
…52…8.4…3…9…5.1…6…2…7…3…6…1…7.4…3.
end
Sample Output
527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936
搜索思路:从没有数字的格子开始递归搜索,如果当前填入的数字不合法,则填入下一个当前状态合法的数据,直到所有数据填写完毕。
剪枝优化策略:
1.优化搜索顺序:从当前能填合法数字最少的位置开始填数字。
2.如何最快的求出当前的合法数字,以及某个点填入数字后,其他点状态的更新。
解决办法:
对于每行,每列,每个九宫格,分别用9位二进制数来表示那些数字可以填。
例如:row[i] = 000010101(二进制)表示第i行可以填入1,3,5
而对于某个位置的状态,则为该点所在上述三种状态的&运算
int get(int x,int y){return row[x] & list[y] & block[(x/3)*3+y/3];
}
ac代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 9;
const int M = (1<<9);
char str[100];
int row[N+2],list[N+2],block[N+2];//行,列和区域
int n;
int cnt[M],map[M];
int a[N+2][N+2];int get(int x,int y){return row[x] & list[y] & block[(x/3)*3+y/3];
}int lowbit(int x){return x&(-x);
}bool dfs(int nn){int i,j;if(nn == 81) return true;//找出来最少的选择方案int x,y,mint = M-1;//最小数量for(i = 0;i<N;i++){for(j = 0;j<N;j++){if(a[i][j] != -1) continue;int t = get(i,j);if(cnt[t]<cnt[mint]){x = i,y = j;mint = t;}}}//当前选择最小的点x,ywhile(mint != 0){int num = map[lowbit(mint)];//当前x,y点的数a[x][y] = num;row[x] -= 1<<num;list[y] -= 1<<num;block[(x/3)*3+y/3] -= 1<<num;//搜索下一层if(dfs(nn+1)){// cout<<x<<" "<<y<<" "<<a[x][y]<<" "<<num<<endl;return true;}// cout<<x<<" "<<y<<endl;//回溯a[x][y] = -1;row[x] += 1<<num;list[y] += 1<<num;block[(x/3)*3+y/3] += 1<<num;//搜索下一个mint -= lowbit(mint);}return false;
}int main(){int i,j;//预处理0——(1<<8)-1的1的个数for(i = 0;i<N;i++) map[1<<i] = i;for(i = 0;i<M;i++){int a = i,cn = 0;while(a != 0){cn++;a -= lowbit(a);}cnt[i] = cn;}while(cin>>str,str[0] != 'e'){//初始化每一行的状态for(i = 0;i<N;i++){row[i] = list[i] = block[i] = (1<<9)-1;}//对行,列的状态进行更改int k = 0;int cntt = 0;//填入的数量for(i = 0;i<N;i++){for(j = 0;j<N;j++){if(str[k]!='.'){//用0-8表示1-9,更加简单cntt++;int t = str[k]-'1';a[i][j] = t;row[i] -= 1<<t;list[j] -= 1<<t;//i,j点位于的块的位置,x = (i/3)*3+(j/3);int x = (i/3)*3+(j/3);block[x] -= 1<<t;}elsea[i][j] = -1;k++;}}dfs(cntt);for(i = 0;i<N;i++){for(j = 0;j<N;j++){printf("%d",a[i][j]+1);}}cout<<endl;}return 0;
}
DFS剪枝——poj3074数独相关推荐
- DFS剪枝优化 小猫爬山 数独
DFS剪枝策略总结 优化搜索顺序 优先搜索分支数少(剩余选择少)的情况 排除等效冗余 若对顺序没有要求 可以将排列转化为组合 可行性剪枝 不合法的情况不进行搜索 最优化剪枝 若当前的"消耗& ...
- POJ2688状态压缩(可以+DFS剪枝)
题意: 给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路: 水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...
- poj2362 DFS+剪枝
题大致做法就是对所有小棒子长度求和sum,sum就是正方形的周长,sum/4就是边长side. 问题就转变为:这堆小棒子能否刚好组合成为4根长度均为side的大棒子 不难了解,小棒子的长度越长,其灵活 ...
- [Leetcode][第39题][JAVA][组合总和][回溯][dfs][剪枝]
[问题描述][中等] [解答思路] 1. 回溯 import java.util.ArrayDeque; import java.util.ArrayList; import java.util.De ...
- 【HDU - 1518】Square (经典的dfs + 剪枝)
题干: Given a set of sticks of various lengths, is it possible to join them end-to-end to form a squar ...
- [DFS|剪枝] leetcode 22 括号生成
[DFS|剪枝] leetcode 22 括号生成 1.题目 题目链接 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合. 示例: 输入:n = 3 输出:[& ...
- poj2248 DFS+剪枝 or BFS
传送门 2248:Addition Chains 描述 An addition chain for n is an integer sequence with the following four p ...
- 2020 ICPC 南京 H Harmonious Rectangle (DFS剪枝+思维)
题目链接H-Harmonious Rectangle_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京) 题目描述 A vertex-colored rectangle is a rec ...
- DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山
DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_&l ...
最新文章
- linux禅道8.1安装教程,Ubuntu 18.4安装禅道9.8.3 linux 64位一键版本
- 区块链论文8,NIPoPoWs,非交互工作量证明之证明
- 《从零构建前后分离web项目》:开篇 - 纵观WEB历史演变
- 重建包含快照的vmdk描述文件。
- 3.1.3 训练/开发/测试集的问题以及注意事项
- makefile常见伪目标(.PHONY 不会去检查目标文件)
- 大学生体测成绩判断c语言_体育改革瞄准高校,体测不过关可能真的毕不了业了...
- DtCms.ActionLabel.Article.cs
- Microsoft 宣布 Visual Studio 2019 发布日期
- SQL纯手写创建数据库到表内内容
- 实现文字左右滚动 javascript
- ajax split len,jQuery Mobile中的data属性
- 阿里云智能总裁行癫全面解读双 11 核心系统 100% 上云是如何实现的
- 使用nodejs-koa2-mysql-sequelize-jwt 实现项目api接口
- linux phpcms,PHPCMS任意文件下载之exp编写
- java面试(JVM)
- html5直播服务端搭建,直播推流服务器端搭建
- keypress,keydown,keyup的区别:
- Eureka在有虚拟网卡的情况下获取正确的IP
- 基于NI VeriStand的AMESIM生成DLL文件实时仿真流程