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;
}
}
最新文章
- <;script>;元素的位置
- eclipse中去掉Js/javsscript报错信息
- Android实战--电话拨号器
- MYSQL性能调优: 对聚簇索引和非聚簇索引的认识
- 如何避免测试人员提交重复的Bug
- HDU2825 Wireless Password(AC自动机+状压DP)
- NeHe OpenGL教程 第十课:3D世界
- Silverlight读取Zip文件中的图片与视频
- c# 语法5.0 新特性 转自网络
- 自签名SSL生成
- 元器件选型(一)ESD、TVS参考资料
- js Get中文乱码 转码
- 随笔二-https://www.cnblogs.com/shang1680/p/9657994.html
- Oracle 12 Rman增量备份
- rabbitmq web管理
- 移动端web页面开发常用的头部标签设置
- java 编译 运行 及 引用外部 jar 包的方法
- Java进阶 线程安全
- 微信小程序调用接口返回数据或提交数据
- 第三百四十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—cookie禁用、自动限速、自定义spider的settings,对抗反爬机制