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 3 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.

输入

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”.

输出

For each test case, print a line representing the completed Sudoku puzzle.

样例输入

.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

样例输出

527389416819426735436751829375692184194538267268174593643217958951843672782965341

416837529982465371735129468571298643293746185864351297647913852359682714128574936

来源

Stanford Local 2006

题解:

这里使用了lowbit来优化当前的方案,存入二进制数后可以用Lowbit搜索每一位。

所以这说不定就是除了某d开头算法外数独较快的解法了吧。

#include <bits/stdc++.h>
#define lowbit(x) (x & (-x))
using namespace std;
char ch[12][12];
int hang[12], lie[12], gong[12], cnt[1200], num[1200], tot;
int get(int x, int y) { return (x / 3) * 3 + y / 3; }
void flip(int x, int y, int z) {
hang[x] ^= (1 << z);
lie[y] ^= (1 << z);
gong[get(x, y)] ^= (1 << z);
return;
}
bool dfs(int now) {
if (!now)
return 1;
int mn = 10, x, y;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++) {
if (ch[i][j] != '.')
continue;
int val = hang[i] & lie[j] & gong[get(i, j)];
if (!val)
return 0; //矛盾,回退
if (cnt[val] < mn) {
mn = cnt[val];
x = i, y = j;
}
}
int val = hang[x] & lie[y] & gong[get(x, y)];
for (int i = val; i; i -= lowbit(i)) {
int which = num[lowbit(i)];
ch[x][y] = '1' + which;
flip(x, y, which);
if (dfs(now - 1))
return 1;
flip(x, y, which);
ch[x][y] = '.';
}
return 0;
}
char yyh[12000];
signed main() {
for (int i = 0; i < (1 << 9); i++)
for (int j = i; j; j -= lowbit(j))
cnt[i]++; //有几个1
for (int i = 0; i < 9; i++)
num[1 << i] = i;
while (scanf("%s", yyh) && yyh[0] != 'e') {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
ch[i][j] = yyh[i * 9 + j];
for(int i=0;i<9;i++) hang[i]=lie[i]=gong[i]=(1<<9)-1;
tot=0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (ch[i][j]!='.') flip(i,j,ch[i][j]-'1');
else tot++;
dfs(tot);
for(int i=0;i<9;i++) for(int j=0;j<9;j++) cout<<ch[i][j];
puts("");
}
return 0;
}

POJ3074 Sudoku(lowbit优化搜索)的更多相关文章

  1. POJ3074 Sudoku

    POJ3074 Sudoku 与POJ2676相比,这一题搜索时每一步都找到最好确定的点进行枚举 对于每行.每列.每个九宫格,都分别用一个9位二进制数保存还有那些数还可以填 对于每个位置,将其所在行. ...

  2. U盘便携式hexo&博客搭建&极速纯净低bug主题推荐&部署到coding&SEO优化搜索

    指南:U盘便携式hexo&博客搭建&极速纯净低bug主题推荐&部署到coding&SEO优化搜索   U盘便携式hexo随处写博客 简述:在任意一台联网的电脑上续写he ...

  3. POJ3074 Sudoku 剪枝深(神?)搜

    emm...挺秀的...挺神的? 每行,每列,每宫用一个二进制数表示选或没选的状态,刚开始设没选为1,然后更改状态的时候异或一下就好了: 这样可以通过lowbit取出每一个没有选过的数:(妙啊? 关于 ...

  4. HDU - 4059: The Boss on Mars (容斥 拉格朗日 小小的优化搜索)

    pro: T次询问,每次给出N(N<1e8),求所有Σi^4 (i<=N,且gcd(i,N)==1) ; sol:  因为N比较小,我们可以求出素因子,然后容斥.  主要问题就是求1到P的 ...

  5. HDU - 5547 Sudoku(数独搜索)

    Description Yi Sima was one of the best counselors of Cao Cao. He likes to play a funny game himself ...

  6. POJ3074 Sudoku —— Dancing Links 精确覆盖

    题目链接:http://poj.org/problem?id=3074 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissio ...

  7. stream,做减法,优化搜索代码。

    做一个搜索,三个输入条件,求这个条件的交集.起初我的思路是按照操作的流程,一步步的来做这三个筛选. let searchResults = []; //step1 根据id搜索,得到一个子集. if ...

  8. POJ3074 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 代码 #include & ...

  9. 数独:dfs+剪枝+位运算+排除冗余+优化搜索顺序(未完)

    和蓝桥杯以前一个题一样,但是数据加强了,博主水平有限,没做出来,先在这里记录一下,这里正解,下面是博主的超时做法.最近准备考研,不能深入学习了. 题目描述 数独是一种传统益智游戏,你需要把一个9 × ...

随机推荐

  1. C++ 判断进程是否存在

    原文:http://blog.csdn.net/u010803748/article/details/53927977?locationNum=2&fps=1 一.判断指定程序名的进程是否存在 ...

  2. 在Qt中使用Font Awesome图标

    官网: http://fontawesome.io/中文网: http://www.fontawesome.com.cn/GitHub: https://github.com/FortAwesome/ ...

  3. intellij idea下面安装热部署插件 JRebel 5.2

    之前一直是用的eclipse的JRebel,因为现在的公司用的是idea,于是尝试了在idea下面安装,把安装的过程中出现的问题记录下. 1.首先是在 idea里面install JRebel,Fil ...

  4. sql查询学习和实践点滴积累

    https://blog.rjmetrics.com/2008/10/28/correlated-subqueries-in-mysql/ http://www.mysqltutorial.org/m ...

  5. js变量作用域--变量提升

    1.JS作用域 在ES5中,js只有两种形式的作用域:全局作用域和函数作用域,在ES6中,新增了一个块级作用域(最近的大括号涵盖的范围),但是仅限于let方式申明的变量. 2.变量声明 var x; ...

  6. java笔记--关于多线程状态的理解和应用

    关于多线程的状态 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3890266.html  "谢谢-- 线程共有6种状态:1 ...

  7. python的文件对象(1)

    1  首先要明确的是,文件只是连续的字节. 数据的传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成. 2  打开文件之门的钥匙--open() open()内建函数成功打开文件后会返回一个 ...

  8. Java学习---程序设计_面试题[2]

    百度2017春招笔试真题编程题集合之买帽子 // 2017-10-09 // 题目描述 // 度度熊想去商场买一顶帽子,商场里有N顶帽子,有些帽子的价格可能相同.度度熊想买一顶价格第三便宜的帽子,问第 ...

  9. 为什么TCP协议终止链接要四次?

    为什么TCP协议终止链接要四次? 1.当主机A确认发送完数据且知道B已经接受完了,想要关闭发送数据口(当然确认信号还是可以发),就会发FIN给主机B. 2.主机B收到A发送的FIN,表示收到了,就会发 ...

  10. December 11th 2016 Week 51st Sunday

    If a thing is worth doing it is worth doing well. 如果事情值得做,那就做好. If it is worth doing, then it is wor ...