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. MySQL数据库(7)----数据库的选择、创建、删除和更改

    1.选择数据库 使用 USE 语句可以选择数据库,并把它指定为MySQL服务器连接的默认(当前)数据库: USE db_name; 要想选择数据库,用户必须要具备相应的访问权限:否则,会出现错误提示. ...

  2. ORACLE数据仓库学习记录

    一.数据仓库安装 安装ORACLE DATABASE 10g Release 2 ORACLE数据库版本是:10.2.0.1.0(服务器).执行基本安装(安装全部的组件)并创建示例数据库. 安装ORA ...

  3. Volley1--为什么说Volley适合数据量小,通信频繁的网络操作

    前言 网络编程对于客户端来说是一块及其重要的地方,使用高效的网络请求框架将为你的系统产生很大的影响.而Volley作为谷歌的一个开源项目,炙手可热.有很多中小型公司的安卓移动客户端的网络程序都是基于v ...

  4. 应用程序和Activity

    Android 应用程序的组成部分 Android应用程序由各个组件组成,并使用Manifest绑定到一起,Manifest描述了每一个组件和它们之间的交互方式,还用于指定权限,硬件,平台以及应用程序 ...

  5. JMeter测试WEB性能入门

    一.JMeter介绍 1.Apache JMeter是什么 Apache JMeter 是Apache组织的开放源代码项目,是一个100%纯Java桌面应用,用于压力测试和性能测量.它最初被设计用于W ...

  6. 如何写自定义的AlertView

    如何写自定义的AlertView 效果 说明 考虑到后面的可定制性以及可维护性,本人用AbstractAlertView定义了AlertView抽象的基类,实现通过子类来完成. 注:这只是粗略的写了一 ...

  7. [翻译] VICMAImageView

    VICMAImageView https://github.com/vitoziv/VICMAImageView Change image view's content mode with your ...

  8. setfacl 命令的常用用法

    setfacl命令----可以用来细分linux下的文件权限. chmod命令----可以把文件权限分为u,g,o三个组,而setfacl可以对每一个文件或目录设置更精确的文件权限. 换句话说,set ...

  9. Linq使用技巧及查询示例(一)

    Linq的使用大体分为两种:语句表达式   和  方法 首先,我们要在控制器中定义好context private ApplicationDbContext db = new ApplicationD ...

  10. 删除 maven仓库,更新失败的jar包命令

    set REPOSITORY_PATH=D:\maven_cpbsrem ص‎شعثرث÷...for /f "delims=" %%i in ('dir /b /s " ...