Sudoku is one of the metaphysical techniques. If you understand the essence of it, you will have the feeling of being immortal, laughing and laughing with joy.............................................................(audience:"We need't such a geomancer!You can get out!!")

  Oh,I'm sorry.Then let's getting down to business as quickly as possible.

The meaning of the problem isn't hard for us to understand.And it is more friendly to those who have played sudoku.But don't worry if you didn't heard about this kind of game,for there's few skills of formal competition.What you have to do is to memorize its basic rules.

  OK.Now,let's think of the solution of this problem.You may want to enumerate all the alternative numbers in the blanks,then check if it's lawful.Good!it's the first algorithm we've thought of.But there's great room for progress.In fact,when people play sudoku,they will write down candidates in each blank.We can record which number we can use in one blank and try using it.To realize it,we can use state compression to save alternative numbers in each row,column and gong.After that,we can choose the blank which has the least candidates to have test-fill until all the blanks are filled.Don't forget to flash back after updating.

  Up to now,we are able to pass POJ2676,but there's still some distance from passing POJ3074.Think of how we search for the blank which has the least candidates and the use of lowbit.We can use an array to record the position of 1 in lowbit(x),and another one array to preprocess the number of 1 in each binary number.My code is below.

  After you get AC in these two sudokus,you can have a try in a harder promblem POJ3076.But you need a more skillful way.Can you find it?

 #include<bits/stdc++.h>

 using namespace std;

 int row[],column[],house[][],h[],cnt[];
char a[][],c;
bool flag; inline int getchoice(int x,int y){
return row[x]&column[y]&house[x/+][y/+];
} inline int lowbit(int x){
return x&-x;
} void dfs(int x,int y){
if(flag) return;
if(x==){
for(int i=;i<=;i++)
for(int j=;j<=;j++) cout<<a[i][j];
cout<<endl;
flag=true;
return;
}
int hx=x/+,hy=y/+;//判断(x,y)在哪一宫
int choice=getchoice(x,y);
while(choice){
int num=lowbit(choice);
choice-=num;
int row0=row[x],column0=column[y],house0=house[hx][hy];
row[x]&=~num;column[y]&=~num;house[hx][hy]&=~num;
a[x][y]=h[num]+'';
int minn=,xx=,yy;
for(int i=;i<=;i++)
for(int j=;j<=;j++){
if(a[i][j]!='.') continue;
int cal=cnt[getchoice(i,j)];
if(cal<minn){
xx=i;yy=j;
minn=cal;
}
}
dfs(xx,yy);
row[x]=row0;column[y]=column0;house[hx][hy]=house0;
}
a[x][y]='.';
} int main(){
for(int i=;i<=;i++) h[<<i]=i;//预处理lowbit(x)后x中1的位置(即2^n中n的值)
for(int i=;i<;i++)
for (int j=i;j;j-=lowbit(j))
cnt[i]++;//题解中的好方法,预处理每一个二进制数中1的数量;
cin>>c;
while(c!='e'){
for(int i=;i<=;i++)
for(int j=;j<=;j++)
row[i]=column[j]=house[i/+][j/+]=;
a[][]=c;
for(int j=;j<=;j++) scanf("%c",&a[][j]);
for(int i=;i<=;i++)
for(int j=;j<=;j++) scanf("%c",&a[i][j]);
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(a[i][j]!='.'){
int num=a[i][j]-'';
num=pow(,num);
row[i]&=~num;
column[j]&=~num;
house[i/+][j/+]&=~num;//预处理每行、每列、每宫可用的数字
}
flag=false;
int minn=,xx=,yy;
for(int i=;i<=;i++)
for(int j=;j<=;j++){
if(a[i][j]!='.') continue;
int cal=cnt[getchoice(i,j)];
if(cal<minn){
xx=i;yy=j;
minn=cal;
}
}
dfs(xx,yy);
cin>>c;
}
return ;
}

Sudoku(POJ2676/3074)的更多相关文章

  1. POJ 3074 Sudoku (Dancing Links)

    传送门:http://poj.org/problem?id=3074 DLX 数独的9*9的模板题. 具体建模详见下面这篇论文.其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中 ...

  2. POJ 2676 Sudoku(深搜)

    Sudoku Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total Submi ...

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

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

  4. UESTC - 1222 Sudoku(深搜)

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

  5. HDU 3111 Sudoku(精确覆盖)

    数独问题,输入谜题,输出解 既然都把重复覆盖的给写成模板了,就顺便把精确覆盖的模板也写好看点吧...赤裸裸的精确覆盖啊~~~水一水~~~然后继续去搞有点难度的题了... #include <cs ...

  6. LeetCode 36 Valid Sudoku(合法的数独)

    题目链接: https://leetcode.com/problems/valid-sudoku/?tab=Description   给出一个二维数组,数组大小为数独的大小,即9*9  其中,未填入 ...

  7. Sudoku(简单DFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5547 数据比较少,直接暴力DFS,检验成立情况即可 AC代码:但是不知道为什么用scanf,print ...

  8. 【POJ - 2676】Sudoku(数独 dfs+回溯)

    -->Sudoku 直接中文 Descriptions: Sudoku对数独非常感兴趣,今天他在书上看到了几道数独题: 给定一个由3*3的方块分割而成的9*9的表格(如图),其中一些表格填有1- ...

  9. sudoku 心得 视觉消除法(Visual Elimination)

    虽然我是程序员,但这里只介绍人类的思维方法. 这个方法我是从这里看到的: https://www.learn-sudoku.com/visual-elimination.html Most peopl ...

随机推荐

  1. opencv 之 transformation

    getAffineTransform() : calculates an affine transform from three pairs of the corresponding points. ...

  2. ES6学习笔记(函数)

    1.函数参数的默认值 ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面. function log(x, y = 'World') { console.log(x, y); } log(' ...

  3. 微信小程序记账本进度七

    最后大体上完成了,但是好像少了点功能,整体并不是特别华丽

  4. jqgrid修改表格内容为居中

    看了手册没有发现自带的方法,所以使用了自定义css <style> #tableDataSearch tr td{ text-align:center; } </style>

  5. shell中脚本调试----学习

    1.使用dos2unix命令处理在windows下开发的脚本 将windows下编辑的脚本放置到linux下执行的情况如下: [root@ks ~]# cat -v nginx.sh #!/bin/b ...

  6. android 7.0+ FileProvider 访问隐私文件 相册、相机、安装应用的适配

    从 Android 7.0 开始,Android SDK 中的 StrictMode 策略禁止开发人员在应用外部公开 file:// URI.具体表现为,当我们在应用中使用包含 file:// URI ...

  7. 把多个字符串里面的项写到不同的对象中,然后在push到一个数组中

    otherUserNames: "甲,乙,丙,丁"otherUserIds: "10008750,10008711,10003348,10008747" oth ...

  8. 一键脚本清理DEBIAN系统无用组件 减少系统资源

    虽然如今我们选择服务器资源都比较多,以前我们看到很多128MB内存.甚至32MB内存的建站网站,感觉特别羡慕.其实这些也不是难事,相比之下,DEBIAN系统比CENTOS系统占用资源少,然后我们需要进 ...

  9. Codeforces 1083E The Fair Nut and Rectangles

    Description 有\(N\)个左下定点为原点的矩阵, 每个矩阵\((x_i,~y_i)\)都有一个数\(a_i\)表示其花费. 没有一个矩阵包含另一个矩阵. 现要你选出若干个矩阵, 使得矩阵组 ...

  10. EasyPR源码剖析(3):车牌定位之颜色定位

    一.简介 对车牌颜色进行识别,可能大部分人首先想到的是RGB模型, 但是此处RGB模型有一定的局限性,譬如蓝色,其值是255,还需要另外两个分量都为0,不然很有可能你得到的值是白色.黄色更麻烦,它是由 ...