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

最后终于碰上了位运算优化的题目,虽然学会了发现不难,我们就来看看这个题怎么做!

首先明确一件事,&代表两个状态取交集,这样就更快的到两个状态的共有部分,详解在代码中!

#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<bitset>
#include<cstdio>
#include<cstring>
#define Swap(a,b) a^=b^=a^=b
#define cini(n) scanf("%d",&n)
#define cinl(n) scanf("%lld",&n)
#define cinc(n) scanf("%c",&n)
#define cins(s) scanf("%s",s)
#define coui(n) printf("%d",n)
#define couc(n) printf("%c",n)
#define coul(n) printf("%lld",n)
#define speed ios_base::sync_with_stdio(0)
#define Max(a,b) a>b?a:b
#define Min(a,b) a<b?a:b
#define mem(n) memset(n,0,sizeof(n))
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e6+;
const double esp=1e-;
//-------------------------------------------------------// const int N=;
char a[N*N+N];
int R[],L[],C[][];
int one[<<N],mp[<<N];//通过lowbit,找到每一位1对应的位置
inline int lowbit(int n)
{
return n&-n;
}
inline void init()//初始化,每个状态位赋值为1
{ for(int i=; i<N; i++){
R[i]=L[i]=(<<N)-;
} for(int i=; i<; i++)
for(int j=; j<; j++)
C[i][j]=(<<N)-;
}
inline int get(int x,int y) // 找到当前位置能填的状态
{
return L[y]&R[x]&C[x/][y/];
}
bool dfs(int n)
{
if(n==)
return ;
//cout<<n<<' ';
int x,y,mini=;
for(int i=; i<N; i++) //寻找最少填数点
{
for(int j=; j<N; j++)
{
if(a[i*N+j]!='.')
continue;
int minT=one[get(i,j)];
if(minT<mini)
{
x=i;
y=j;
mini=minT;
}
}
}
//cout<<x<<' '<<y<<endl;
int T=get(x,y);
//cout<<T<<endl;
for(int i=T; i; i-=lowbit(i)) //遍历每一位1所代表的的状态,看不懂状态,打个表就行了。
{
int w=mp[lowbit(i)];
a[x*N+y]=w+'';
R[x]-=<<w;
L[y]-=<<w;
C[x/][y/]-=<<w;
if(dfs(n-))
return ;
a[x*N+y]='.';
R[x]+=<<(w);
L[y]+=<<(w);
C[x/][y/]+=<<w;
}
return ;
}
int main()
{
for(int i=; i< <<N; i++)
{
int s=;
for(int j=i; j; j-=lowbit(j))s++;
one[i]=s; //统计2的N次方内所有的数的1的个数,这样用到时就不用算了
}
for(int i=;i<N;i++) mp[<<i]=i;
while(cin>>a&&a[]!='e')
{
int k=,cnt=;
init();
for(int i=; i<N; i++) //预处理,得到还有多少数需要填,处理一下状态
{
for(int j=; j<N; j++,k++)
{
if(a[i*N+j]=='.')
{
cnt++;
continue;
};
int T=(<<(a[k]-''));
R[i]-=T;//代表这一行的状态中填了a[k]这个数了
L[j]-=T;
C[i/][j/]-=T;
}
}
if(dfs(cnt))
cout<<a<<endl;
}
}

POJ - 3074 Sudoku (搜索)剪枝+位运算优化的更多相关文章

  1. 模拟赛T5 : domino ——深搜+剪枝+位运算优化

    这道题涉及的知识点有点多... 所以还是比较有意思的. domino 描述 迈克生日那天收到一张 N*N 的表格(1 ≤ N ≤ 2000),每个格子里有一个非 负整数(整数范围 0~1000),迈克 ...

  2. 数独求解问题(DFS+位运算优化)

    In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For exa ...

  3. N皇后解法以及位运算优化

    N皇后解法以及位运算优化 观察棋盘,要求皇后之间不能处在同行同列同一条斜线,求使得每行都有一个皇后的放置方法共有多少种. 每尝试放置一个皇后,都可以把该位置所在的行.列标号用一个数组标记,含义表示该行 ...

  4. N皇后-位运算优化

    N皇后问题 时间限制: 5 Sec  内存限制: 128 MB 题目描述 魔法世界历史上曾经出现过一个伟大的罗马共和时期,出于权力平衡的目的,当时的政治理论家波利比奥斯指出:“事涉每个人的权利,绝不应 ...

  5. poj 2777 Count Color - 线段树 - 位运算优化

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42472   Accepted: 12850 Description Cho ...

  6. POJ 3074 Sudoku (DLX)

    Sudoku Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  7. [poj]开关类问题 枚举 位运算

    poj 1222  EXTENDED LIGHTS OUT 开关只有两种方案 按和不按,按两次相当于关 只用枚举第一排开关的按法即可,剩下的行为使上一排的灯全部关闭,按法可以确定,并且是唯一的. 最后 ...

  8. POJ 1166 The Clocks [BFS] [位运算]

    1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的 ...

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

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

随机推荐

  1. MySQL入门,第六部分,关系代数

    关系代数是一种集合操作为基础过程化查询语言,特点:运算对象是关系,运算结果亦为关系 一.关系代数的特点 运算对象:关系 运算结果:关系 运算符:四类 集合运算符 专门的关系运算符 算术比较符 逻辑运算 ...

  2. Linux网络篇,ssh原理及应用

    一.对称加密与非对称加密 对称加密: 加密和解密的秘钥使用的是同一个.    非对称加密: 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥:简称公钥和私钥 对称加密 对称加密的密 ...

  3. Python zipfile模块学习

    转载自https://www.j4ml.com/t/15270 import zipfile import os from zipfile import ZipFile class ZipManage ...

  4. 超详细Go语言源码目录说明

    开源项目「go home」聚焦Go语言技术栈与面试题,以协助Gopher登上更大的舞台,欢迎go home~ 导读 学习Go语言源码的第一步就是了解先了解它的目录结构,你对它的源码目录了解多少呢?今天 ...

  5. 简单完成Excel导出

    Excel的导出只需要三步即可完成: 1,完成excel的工具类编写,直接复制即可 package cn.com.bcl.util; import java.util.List; import org ...

  6. 前端架构演进及主流UI

    @ 目录 前端三要素 JavaScript 框架 NodeJs 常用UI框架 前后端分离的演进 MVVM模式 总结 前端演进到现在,各种技术框架已经层出不穷了,作为一名开发少不了要干一些前端的活儿,那 ...

  7. 详解 缓冲区(Buffer 抽象类)

    在本篇博文中,本人主要讲解NIO 的两个核心点 -- 缓冲区(Buffer) 和 通道 (Channel)之一的 缓冲区(Buffer), 有关NIO流的其他知识点请观看本人博文<详解 NIO流 ...

  8. JAVA的synchronized写法

    使用关键字synchronized的写法比较多,常用的有如下几种,代码如下: public class MyService { synchronized public static void test ...

  9. js的中文英文排序

    本例主要实现 中文汉字按拼音排序的方法和英文按照首字母排序的方法. //要排序的数据 let data = [ {chinese: '蔡司', english: 'Chase'}, {chinese: ...

  10. python 基础篇 错误和异常处理

    语法错误 所谓语法错误,也就是你写的代码不符合编程规范,无法被识别与执行,比如下面这个例子: if name is not None print(name) If 语句漏掉了冒号,不符合 Python ...