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. c3p0数据源的第一次尝试

    开始补习 以前学习过的基础 正在尝试从c3p0 获取到connection 好的,首先上代码吧 public static DataSource ds = null; static { ComboPo ...

  2. Linux 进程同步和通信

    为了同步进程所以需要进程通信 管道(有名:文件形式存在,无名:仅限于父子进程间通信) 消息队列 信号量 共享存储 套接字(可用于不同机器)

  3. 实际项目中如何使用git命令

    使用工具:Git Bash 工作空间项目存放路径C:/用户/git/demoProject 操作步骤: 1.切换到git项目路径 cd  git/demoProject 2.git status   ...

  4. IO输入输出流

    在Java中进行文件的读写,Java IO流是必备的知识. IO流指 的是输入输出流,用来处理设备上的数据.这里的设备指硬盘,内存,键盘录入,网络传输等. 按处理数据类型来分:字节流和字符流. 按流的 ...

  5. js判断一个变量是数组还是对象

    判断变量是数组还是对象,使用Object.prototype.toString.call(),兼容性好,切勿使用typeof来判断对象或者数组,因为typeof得到的都是object: functio ...

  6. bootstrap模态框手动关闭遮盖层不消失

    模态框中 加载了一个子页面 子页面中调教表单之后想根据执行结果手动关闭模态框,最初尝试了以下几种方案: 1.$("#myModal").modal('hide');//模态框关闭 ...

  7. c#: 创建桌面快捷方式

    App适配输出方式时发现问题,聊做备忘. 需要注意的是:不要直接引用Interop.IWshRuntimeLibrary.dll程序集,因为它可能是x86或x64的,倘若程序以Any CPU方式编译, ...

  8. winform使用PrintDocument控件打印以及oledb驱动

    代码,需要加入的控件:PrintDocument.PageSetupDialog.PrintDialog.PrintPreviewDialog.BackgroundWorker,控件的Document ...

  9. chip8模拟器的python3实现-2-指令介绍

    CHIP指令表 CHIP-8有35个指令,都为两字节长,以大端方式存储.指令表的指令格式规定如下: NNN:地址 NN:8位常量 N:4位常量 V:寄存器 X和Y:4位,标识寄存器 PC:程序计数器 ...

  10. ubuntu-14.04安装最新tensorflow记录

    1.安装英伟达驱动./NVIDIA-Linux-x86_64-384.69.runnvidia-smi成功表示驱动ok 2.安装cudadpkg -i cuda-repo-ubuntu1404-8-0 ...