POJ3076 Sudoku

  • 本题为16*16宫格
  • 剪枝见代码
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=; #define res register int
int map[N][N];
unsigned short t[N][N];
//table[i,j](二进制)表示(i,j)可以填的数,0可填,1不可填
int filled(); inline void my_fill(int x,int y,int a)//(x,y)填a
{
filled++;
map[x][y]=a;
t[x][y] |=<<(a-);
for(res i= ; i< ; i++)
t[x][i] |=<<(a-),
t[i][y] |=<<(a-);
int r=x/*,c=y/*;//(r,c)表示(x,y)所在的16宫格的左上角的格子,(从(0,0)开始)
for(res i= ; i< ; i++)
for(res j= ; j< ; j++) t[r+i][j+c] |=<<(a-);
} //判断x中0的个数是否只有1个
int count_zero(unsigned short x)
{
int p(-);
for(int i=;x;i++)
{
if(x&==)
{
if(p!=-) return -;
p=i;
}
x>>=;
}
return p;
} //第x行,数字k+1,返回>0表示唯一可填的k+1的位置,-1表示有多个可以填的位置或已经填过,-2不能填
inline int col(int x,int k)
{
int p(-);
for(res y= ; y< ; y++)
{
if(map[x][y]==k+) return -;//已经填过
if(map[x][y]>) continue;
if((t[x][y]&(<<k))==)
{
if(p!=-) return -;//多次出现
p=y;
}
}
if(p!=-) return p;
return -;
} //第y列,数字k
inline int row(int y,int k)
{
int p=-;
for(res x= ; x< ; x++)
{
if(map[x][y]==k+) return -;
if(map[x][y]>) continue;
if((t[x][y]&(<<k))==)
{
if(p!=-) return -;
p=x;
}
}
if(p!=-) return p;
return -;
} inline void grid(int r,int c,int k,int &x,int &y)
//以(r,c)为左上角的16宫格,数字k+1,(x,y)为唯一可填坐标[
{
x=-;
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
{
if(map[r+i][c+j]==k+) {x=-; return ;}
if(map[r+i][c+j]>) continue;
if((t[r+i][c+j]&(<<k))==)
{
if(x!=-) {x=-; return ;}
x=i,y=j;
}
}
} inline int count_1(unsigned short x) {
int tmp();
while(x) {
if(x&) tmp++;
x>>=;
}
return tmp;
} bool search()
{
if(filled==) return true;
//先看是否有能确定的格子
for(res x= ; x< ; x++)
for(res y= ; y< ; y++)
{
if(map[x][y]>) continue;
int k=count_zero(t[x][y]);
if(k!=-) my_fill(x,y,k+);
}
for(res x= ; x< ; x++)
for(res k= ; k< ; k++)
{
int y=col(x,k);
if(y==-) return false;
if(y!=-) my_fill(x,y,k+);
}
for(res y= ; y< ; y++)
for(res k= ; k< ; k++)
{
int x=row(y,k);
if(x==-) return false;
if(x!=-) my_fill(x,y,k+);
}
for(res r= ; r< ; r+=)
for(res c= ; c< ; c+=)
for(res k= ; k< ; k++)
{
int x,y;
grid(r,c,k,x,y);
if(x==-) return false;
if(x!=-) my_fill(r+x,c+y,k+);
}
if(filled==) return true;
int t_filled(filled);
int t_map[N][N];
unsigned short t_t[N][N];
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
t_map[i][j]=map[i][j],
t_t[i][j]=t[i][j];
//找可能情况最少的格子来枚举
int mx,my,mn=;
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
{
if(map[i][j]>) continue;
int r=-count_1(t[i][j]);
//未确定的
if(r<mn)
{
mn=r; mx=i; my=j;
}
}
for(res k= ; k< ; k++)
if((t[mx][my]&<<k)==)
{
my_fill(mx,my,k+);
if(search()) return true;
filled=t_filled;
for(res i= ; i< ; i++)
for(res j= ; j< ; j++)
map[i][j]=t_map[i][j],
t[i][j]=t_t[i][j];
}
return false;
} char ar[N];
int main()
{
while()
{
filled=;
memset(map,,sizeof(map)); memset(t,,sizeof(t));
for(int i= ; i< ; i++)
{
if(scanf("%s",ar)==EOF) return ;
for(int j= ; j< ; j++)
if(ar[j]!='-') my_fill(i,j,ar[j]-'A'+);
}
search();
for(res i= ; i< ; i++)
{
for(res j= ; j< ; j++) printf("%c",map[i][j]+'A'-);
puts("");
}
puts("");
}
return ;
}

POJ3076 Sudoku的更多相关文章

  1. POJ3076 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的16*16数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 学完这个之后,再 ...

  2. 【转】Dancing Links题集

    转自:http://blog.csdn.net/shahdza/article/details/7986037 POJ3740 Easy Finding [精确覆盖基础题]HUST1017 Exact ...

  3. dancing links 题集转自夏天的风

    POJ3740     Easy Finding [精确覆盖基础题] HUST1017    Exact cover [精确覆盖基础] HDOJ3663 Power Stations [精确覆盖] Z ...

  4. Sudoku(POJ2676/3074)

    Sudoku is one of the metaphysical techniques. If you understand the essence of it, you will have the ...

  5. Leetcode 笔记 36 - Sudoku Solver

    题目链接:Sudoku Solver | LeetCode OJ Write a program to solve a Sudoku puzzle by filling the empty cells ...

  6. [LeetCode] Sudoku Solver 求解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  7. [LeetCode] Valid Sudoku 验证数独

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

  8. LeetCode 36 Valid Sudoku

    Problem: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board ...

  9. 【leetcode】Valid Sudoku

    题目简述: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board cou ...

随机推荐

  1. ubuntu14.04 64 位 vmware tools 问题2

    当提示说open-vm-tools版本太低时可以这样解决 0.使用最新版本12.5的vmware player. 1.sudo apt-get autoremove open-vm-dkms open ...

  2. 浅谈c/c++中的指针问题

    首先给出几种指针类型来作出区分,不看后面的解析如果可以自己分辨正确那么就算对指针有一个很好的掌握了,就没有必要再去看后面的解析,如果不能完全区分,那么就有必要仔细看看后面解析. 1 Char * p  ...

  3. Python爬虫实战一之爬取糗事百科段子

    大家好,前面入门已经说了那么多基础知识了,下面我们做几个实战项目来挑战一下吧.那么这次为大家带来,Python爬取糗事百科的小段子的例子. 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把 ...

  4. strlen头文件

    #include <string.h> 函数strlen strsep 等等

  5. 【原创】cython and python for kenlm

    未经允许不可转载 Kenlm相关知识 Kenlm下载地址 kenlm中文版本训练语言模型 如何使用kenlm训练出来的模型C++版本 关于Kenlm模块的使用及C++源码说明 加载Kenlm模块命令 ...

  6. 设计模式(java)--模版方法模式之任务分配

    转自:http://blog.csdn.net/zhengzhb/article/details/7405608 定义:定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构 ...

  7. web测试——完结感言

    1.在小组所有成员一人找出了博客园的2个小bug. 2.杨瑞丰与李建文完成了用户调研和定量评价. 3.张颖与汪鸿也完成了产品分析和与CSDN的横向比较. 4.胡俊辉一个人总结所有人的问题与结果,进行了 ...

  8. MongoDB与CouchDB全方位对比(转)

    出处:http://www.csdn.net/article/2011-03-21/294226 本文见于MongoDB官方网站,MongoDB与CouchDB很相似,他们都是文档型存储,数据存储格式 ...

  9. linux 删除文件,某个文件例外

    # shopt -s extglob      (打开extglob模式) # rm -fr !(file1)

  10. 【转载】实战mysql分区(PARTITION)

    转载地址:http://lobert.iteye.com/blog/1955841 前些天拿到一个表,将近有4000w数据,没有任何索引,主键.(建这表的绝对是个人才) 这是一个日志表,记录了游戏中物 ...