题意: 给出一个9*9的矩阵,有一些格子已经填了数,有一些是.代表未填。求任意一组解使得每行包含1~9,每列包含1~9,每个小矩形(3*3)包含1~9。

解析: 精确覆盖DLX的经典题目,每一行代表要填数的情况,列共有81*4行,第一个81行代表第i行j列放了数,第二个81列代表第i行放的数k,第三个81列

代表第j列放的数k,第四个81行代表第i个小矩形放的数k。对于字符为.的情况添加9行,对于字符为数字的情况添加一行。然后就是跑一遍DLX,保存一下答案

输出即可。

代码

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int INF=1e9+;
const int ms=*;
const int maxn=ms*;
int ans[maxn];
struct DLX
{
int n,id;
int L[maxn],R[maxn],U[maxn],D[maxn];
int C[maxn],S[maxn],loc[maxn][];
int H[ms];
void init(int nn=)
{
n=nn;
for(int i=;i<=n;i++) U[i]=D[i]=i,L[i]=i-,R[i]=i+;
L[]=n; R[n]=;
id=n;
memset(S,,sizeof(S));
memset(H,-,sizeof(H));
}
void Link(int x,int y,int px,int py,int k)
{
++id;
D[id]=y; U[id]=U[y];
D[U[y]]=id; U[y]=id;
loc[id][]=px,loc[id][]=py,loc[id][]=k;
C[id]=y; S[y]++;
if(H[x]==-) H[x]=L[id]=R[id]=id;
else
{
int a=H[x];
int b=R[a];
L[id]=a; R[a]=id;
R[id]=b; L[b]=id;
H[x]=id;
}
}
void Remove(int c)
{
L[R[c]]=L[c];
R[L[c]]=R[c];
for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
{
U[D[j]]=U[j];
D[U[j]]=D[j];
S[C[j]]--;
}
}
void Resume(int c)
{
for(int i=U[c];i!=c;i=U[i])
for(int j=R[i];j!=i;j=R[j])
{
S[C[j]]++;
U[D[j]]=j;
D[U[j]]=j;
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(int step)
{
if(step==) return true;
if(R[]==) return false;
int Min=INF,c=-;
for(int i=R[];i;i=R[i])
if(Min>S[i]){ Min=S[i]; c=i; }
Remove(c);
for(int i=D[c];i!=c;i=D[i])
{
ans[step]=i;
for(int j=R[i];j!=i;j=R[j]) Remove(C[j]);
if(dfs(step+)) return true;
for(int j=L[i];j!=i;j=L[j]) Resume(C[j]);
}
Resume(c);
return false;
}
}dlx;
int main()
{
char S[];
while(scanf("%s",S)!=EOF)
{
if(S[]=='e') break;
dlx.init(*);
int k=,r=;
for(int x=;x<;x++)
for(int y=;y<;y++)
{
char ch=S[k++];
int a,b,c,d;
if(ch=='.')
{
for(int i=;i<=;i++)
{
a=x*+y+;
b=x*+i+;
c=y*+i++;
int s=(x/)*+y/;
d=s*+i+++;
++r;
dlx.Link(r,a,x,y,i);
dlx.Link(r,b,x,y,i);
dlx.Link(r,c,x,y,i);
dlx.Link(r,d,x,y,i);
}
}
else
{
int i=ch-'';
a=x*+y+;
b=x*+i+;
c=y*+i++;
int s=(x/)*+y/;
d=s*+i+++;
++r;
dlx.Link(r,a,x,y,i);
dlx.Link(r,b,x,y,i);
dlx.Link(r,c,x,y,i);
dlx.Link(r,d,x,y,i);
}
}
dlx.dfs();
int res[][];
for(int i=;i<;i++)
{
int a=ans[i];
int x=dlx.loc[a][],y=dlx.loc[a][],k=dlx.loc[a][];
res[x][y]=k;
}
for(int i=;i<;i++)
for(int j=;j<;j++) printf("%d",res[i][j]);
printf("\n");
}
return ;
}

Poj3074-Sudoku(数独DLX)的更多相关文章

  1. POJ3074 Sudoku

    POJ3074 Sudoku 与POJ2676相比,这一题搜索时每一步都找到最好确定的点进行枚举 对于每行.每列.每个九宫格,都分别用一个9位二进制数保存还有那些数还可以填 对于每个位置,将其所在行. ...

  2. POJ3074 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 代码 #include & ...

  3. HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 Problem Description Today we play a squiggly sud ...

  4. POJ 3076 / ZOJ 3122 Sudoku(DLX)

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  5. Sudoku 数独游戏

    #include<iostream> using namespace std; bool heng(int **sudo, int a, int b, int value) { bool ...

  6. POJ Sudoku 数独填数 DFS

    题目链接:Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18105   Accepted: 8772   Sp ...

  7. leetcode 37. Sudoku Solver 36. Valid Sudoku 数独问题

    三星机试也考了类似的题目,只不过是要针对给出的数独修改其中三个错误数字,总过10个测试用例只过了3个与世界500强无缘了 36. Valid Sudoku Determine if a Sudoku ...

  8. valid sudoku(数独)

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

  9. POJ 2676 Sudoku (数独 DFS)

      Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14368   Accepted: 7102   Special Judg ...

  10. POJ3074 Sudoku(lowbit优化搜索)

    In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For exa ...

随机推荐

  1. poj2723-Get Luffy Out

    一道2-SAT问题,每对钥匙需要加一条边,每扇门上的对应的要用的钥匙加一条边. 其实求解2-SAT问题,关键在于找到不能同时成立的条件,例如在本题中,每对钥匙不能同时使用,每扇门上的钥匙不能同时不使用 ...

  2. 面试题32.从1到n整数中1出现的次数

    题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从 1到12这些整数中包含1的数字中1,10,11和12,1一共出现了5次 本题可以直接变量1到n的n个数然后分别计 ...

  3. 手游与App测试如何快速转型? —— 过来人科普手游与App测试四大区别

    随着智能设备的普及和移动互联网的兴起,各家互联网巨头纷纷在往移动端布局和转型,同时初创的移动互联网公司也都盯着这个市场希望分一杯羹.在这个大环境下,互联网的重心已经慢慢从Web端转向了移动端,而移动端 ...

  4. iOS键盘遮挡输入框,输入区域自动上移

    在iOS开发过程当中,遇到关于键盘遮挡输入框的问题,经过网络参考与实践,总结如下: 登录窗口,上下放置两个UITextField,一个用户名,一个密码,放置的在屏幕下方1/3处,当点击用户名时,自动弹 ...

  5. NetAnalyzer笔记 之 六 用C#打造自己的网络连接进程查看器(为进程抓包做准备)

    [创建时间:2016-04-13 22:37:00] NetAnalyzer下载地址 起因 最近因为NetAnalyzer2016的发布,好多人都提出是否可以在NetAnalyzer中加入一个基于进程 ...

  6. python scrapy 基础

    scrapy是用python写的一个库,使用它可以方便的抓取网页. 主页地址http://scrapy.org/ 文档 http://doc.scrapy.org/en/latest/index.ht ...

  7. linux系统下怎么安装.deb文件?

    linux系统下怎么安装.deb文件? deb 是 ubuntu .debian 的格式. rpm 是 redhat .fedora .suse 的格式. 他们不通用(尽管能够转换一下). deb是d ...

  8. mini2440裸机试炼之——DMA直接存取 实现Uart(串口)通信

    这个仅仅能作为自己初步了解MDA的开门篇 实现功能: 将字符串数据通过DMA0通道传递给UTXH0,然后在终端 显示.传输数据完后.DMA0产生中断,beep声, LED亮. DMA基本知识 计算机系 ...

  9. C++设计模式---Strategy模式

    一.前言 学习的第一个设计模式!不知道理解的对不对,期望大家一起多交流~ Strategy模式:策略模式,定义了算法族,分别封装起来,此模式可以让算法的变化独立于使用算法的客户.Strategy模式将 ...

  10. 验证docker的Redis镜像也存在未授权访问漏洞

    看到了这篇老外的博客:Over 30% of Official Images in Docker Hub Contain High Priority Security Vulnerabilities于 ...