题目连接

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数独相关推荐

  1. DFS剪枝优化 小猫爬山 数独

    DFS剪枝策略总结 优化搜索顺序 优先搜索分支数少(剩余选择少)的情况 排除等效冗余 若对顺序没有要求 可以将排列转化为组合 可行性剪枝 不合法的情况不进行搜索 最优化剪枝 若当前的"消耗& ...

  2. POJ2688状态压缩(可以+DFS剪枝)

    题意:       给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路:       水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...

  3. poj2362 DFS+剪枝

    题大致做法就是对所有小棒子长度求和sum,sum就是正方形的周长,sum/4就是边长side. 问题就转变为:这堆小棒子能否刚好组合成为4根长度均为side的大棒子 不难了解,小棒子的长度越长,其灵活 ...

  4. [Leetcode][第39题][JAVA][组合总和][回溯][dfs][剪枝]

    [问题描述][中等] [解答思路] 1. 回溯 import java.util.ArrayDeque; import java.util.ArrayList; import java.util.De ...

  5. 【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 ...

  6. [DFS|剪枝] leetcode 22 括号生成

    [DFS|剪枝] leetcode 22 括号生成 1.题目 题目链接 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合. 示例: 输入:n = 3 输出:[& ...

  7. poj2248 DFS+剪枝 or BFS

    传送门 2248:Addition Chains 描述 An addition chain for n is an integer sequence with the following four p ...

  8. 2020 ICPC 南京 H Harmonious Rectangle (DFS剪枝+思维)

    题目链接H-Harmonious Rectangle_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京) 题目描述 A vertex-colored rectangle is a rec ...

  9. DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山

    DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_&l ...

最新文章

  1. linux禅道8.1安装教程,Ubuntu 18.4安装禅道9.8.3 linux 64位一键版本
  2. 区块链论文8,NIPoPoWs,非交互工作量证明之证明
  3. 《从零构建前后分离web项目》:开篇 - 纵观WEB历史演变
  4. 重建包含快照的vmdk描述文件。
  5. 3.1.3 训练/开发/测试集的问题以及注意事项
  6. makefile常见伪目标(.PHONY 不会去检查目标文件)
  7. 大学生体测成绩判断c语言_体育改革瞄准高校,体测不过关可能真的毕不了业了...
  8. DtCms.ActionLabel.Article.cs
  9. Microsoft 宣布 Visual Studio 2019 发布日期
  10. SQL纯手写创建数据库到表内内容
  11. 实现文字左右滚动 javascript
  12. ajax split len,jQuery Mobile中的data属性
  13. 阿里云智能总裁行癫全面解读双 11 核心系统 100% 上云是如何实现的
  14. 使用nodejs-koa2-mysql-sequelize-jwt 实现项目api接口
  15. linux phpcms,PHPCMS任意文件下载之exp编写
  16. java面试(JVM)
  17. html5直播服务端搭建,直播推流服务器端搭建
  18. keypress,keydown,keyup的区别:
  19. Eureka在有虚拟网卡的情况下获取正确的IP
  20. 基于NI VeriStand的AMESIM生成DLL文件实时仿真流程

热门文章

  1. Annual work summary
  2. 5-10人的创业团队,怎么在半个月内上线一款新产品?
  3. 在IDEA中安装webpack
  4. Android Dialog 解决输入法挡住输入框的问题
  5. 职场纵横之人际关系的55个绝招(4)
  6. IDEA创建父子项目
  7. 63款2022虎年贺岁新春banner素材(附带源文件)
  8. Srt字幕的视频用它就能批量制作
  9. coreldraw x8里线段显示尺寸_CorelDRAW X8快速更换纸张类型和创建自定义的页面尺寸...
  10. Python 虚拟环境 看这一篇就够了