POJ - 3074 Sudoku (搜索)剪枝+位运算优化
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 (搜索)剪枝+位运算优化的更多相关文章
- 模拟赛T5 : domino ——深搜+剪枝+位运算优化
这道题涉及的知识点有点多... 所以还是比较有意思的. domino 描述 迈克生日那天收到一张 N*N 的表格(1 ≤ N ≤ 2000),每个格子里有一个非 负整数(整数范围 0~1000),迈克 ...
- 数独求解问题(DFS+位运算优化)
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For exa ...
- N皇后解法以及位运算优化
N皇后解法以及位运算优化 观察棋盘,要求皇后之间不能处在同行同列同一条斜线,求使得每行都有一个皇后的放置方法共有多少种. 每尝试放置一个皇后,都可以把该位置所在的行.列标号用一个数组标记,含义表示该行 ...
- N皇后-位运算优化
N皇后问题 时间限制: 5 Sec 内存限制: 128 MB 题目描述 魔法世界历史上曾经出现过一个伟大的罗马共和时期,出于权力平衡的目的,当时的政治理论家波利比奥斯指出:“事涉每个人的权利,绝不应 ...
- poj 2777 Count Color - 线段树 - 位运算优化
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42472 Accepted: 12850 Description Cho ...
- POJ 3074 Sudoku (DLX)
Sudoku Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- [poj]开关类问题 枚举 位运算
poj 1222 EXTENDED LIGHTS OUT 开关只有两种方案 按和不按,按两次相当于关 只用枚举第一排开关的按法即可,剩下的行为使上一排的灯全部关闭,按法可以确定,并且是唯一的. 最后 ...
- POJ 1166 The Clocks [BFS] [位运算]
1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的 ...
- 数独:dfs+剪枝+位运算+排除冗余+优化搜索顺序(未完)
和蓝桥杯以前一个题一样,但是数据加强了,博主水平有限,没做出来,先在这里记录一下,这里正解,下面是博主的超时做法.最近准备考研,不能深入学习了. 题目描述 数独是一种传统益智游戏,你需要把一个9 × ...
随机推荐
- python redis 实现简单的消息订阅
python + redis 实现简单的消息订阅 订阅端 import redis from functools import wraps class Subscribe: def __init__( ...
- 微信号网页版api
Django Wechat Api djangowechatapi是基于wxpy和django制作的web应用 安装 使用pip pip install djangowechatapi 源码安装 gi ...
- python使用阿里云oss-sdk
python使用阿里云oss-python-sdk 请访问github获取源码 安装 pip install oss2 安装验证 >>> import oss2 >>&g ...
- Windows恢复分区管控命令reagentc
reagentc命令可以实现Windows恢复分区的开关,创建.删除,状态查看. 可以只管确定当前系统恢复分区所在位置,便于删除多余的恢复分区.
- PHPDocumentor2.8.5 安装,使用及快速上手
PHPDocumentor当前版本是phpDocumentor-2.8.5.tgz 关于PHPDocumentor有什么用,还有其历史,我就不介绍了,直接进入正题.老版本的叫PHPDoc,从1.0开始 ...
- std::string::assign函数
string& assign (const string& str); string& assign (const string& str, size_t subpos ...
- 数据结构和算法(Golang实现)(18)排序算法-前言
排序算法 人类的发展中,我们学会了计数,比如知道小明今天打猎的兔子的数量是多少.另外一方面,我们也需要判断,今天哪个人打猎打得多,我们需要比较. 所以,排序这个很自然的需求就出来了.比如小明打了5只兔 ...
- AJ学IOS(13)UI之UITableView学习(下)汽车名牌带右侧索引
AJ分享,必须精品 先看效果图 代码 ViewController #import "NYViewController.h" #import "NYCarGroup.h& ...
- webWMS开发过程记录(二)- WMS是什么
(参考:WMS-百度百科) 简介 WMS是仓库管理系统(Warehouse Management System)的缩写,是一款标准化.智能化过程导向管理的仓库管理软件仓库管理系统,是通过出入库业务.仓 ...
- App 开发中判断 ios 和 andriod 常用方法便于修复在两类机型样式不一样等缺陷
判断安卓, ios