题意:解数独

分析:

完整的数独有四个充要条件:

1.每个格子都有填数字

2.每列都有1~9中的每个数字

3.每行都有1~9中的每个数字

4.每个9宫格都有1~9中的每个数字

可以转化成精确覆盖问题。每行表示一个格子的一种填法,1~81列表示这个格子的位置,82~162列表示这是哪一行的什么数字,163~243列表示这是哪一列的什么数字,244~324列表示这是哪一个九宫格里的什么数字。每行都把四个1填入这四个区间里的对应位置。最后求出这个01矩阵的精确覆盖就是解。

对于已经确定的点 我们就直接建一行 对于没有确定的点我们就 建k行(k<=9),这样说如果在该行该列或者该3*3的矩阵中存在该数字 则对应的该数字所在的行就没有必要建立了

这样跑一次dlx精确覆盖就ok了

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <string.h>
using namespace std;
const int M=****; struct node{
int c,x,y,k;
};
struct DLX
{
int n,sz;
int S[**];
int row[M],col[M];
int L[M],R[M],U[M],D[M];
int ans[][];
int X[M],Y[M],Cnt[M];
void init(int n)
{
this->n=n;
for(int i=; i<=n; i++)
{
U[i]=i;D[i]=i;
L[i]=i-; R[i]=i+;
}
R[n]=;L[]=n;
sz=n+;
memset(S,,sizeof(S));
}
void addRow(int r,vector<node>columns)
{
int first=sz;
for(int i=; i<columns.size();i++)
{
int c=columns[i].c; X[sz]=columns[i].x; Y[sz]=columns[i].y; Cnt[sz]=columns[i].k;
L[sz]=sz-;
R[sz]=sz+;
D[sz]=c; U[sz]=U[c];
D[U[c]]=sz;U[c]=sz;
row[sz]=r;col[sz]=c;
S[c]++;sz++;
}
R[sz-]=first; L[first]=sz-;
}
#define FOR(i,A,s) for(int i=A[s]; i!=s; i=A[i])
void remove(int c)
{
L[R[c]]=L[c];
R[L[c]]=R[c];
FOR(i,D,c)
FOR(j,R,i)
{
U[D[j]]=U[j];D[U[j]]=D[j];--S[col[j]];
}
}
void restore(int c)
{
FOR(i,U,c)
FOR(j,L,i)
{
++S[col[j]];U[D[j]]=j;D[U[j]]=j;
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(int d)
{
if(R[]==)return true;
else
{
int num=R[];
FOR(i,R,)
{
if(S[i]==) return false;
if(S[num]>S[i])
{
num=i;
}
}
remove(num);
FOR(i,D,num)
{
ans[X[i]][Y[i]]=Cnt[i];
FOR(j,R,i)remove(col[j]);
if(dfs(i+))
{
return true;
}
FOR(j,L,i)restore(col[j]);
}
restore(num);
return false;
}
}
}Link;
bool hasr[][],hasc[][],hasp[][];
char str[];
vector<node> colum;
int main()
{
while(scanf("%s",str)==&&str[]!='e')
{
memset(hasr,false,sizeof(hasr));
memset(hasc,false,sizeof(hasc));
memset(hasp,false,sizeof(hasp));
for(int i=; i<; i++)
for(int j=; j<; j++)
{
if(str[i*+j]!='.')
{
int k=str[i*+j]-'';
hasr[i][k]=true;
hasc[j][k]=true;
hasp[i/ *+j/][k]=true;
}
}
int m=**;
int n=;
Link.init(m);
for(int i=; i<; i++)
for(int j=; j<; j++)
{
int k=;
if(str[i*+j]!='.')
k=str[i*+j]-'';
if(k!=)
{
n++;
colum.clear();
node dot;
dot.k=k;
dot.x=i;
dot.y=j;
dot.c=i*+j+;
colum.push_back(dot);
dot.c=+i*+k;
colum.push_back(dot);
dot.c=+j*+k;
colum.push_back(dot);
dot.c=+(i/*+j/)*+k;
colum.push_back(dot);
Link.addRow(n,colum);
}else {
node dot;
dot.x=i;dot.y=j;
for(int k=; k<=; k++)
{
if(hasr[i][k]==false &&hasc[j][k]==false && hasp[i/*+j/][k]==false)
{
dot.k=k;
colum.clear();
n++;
dot.c=i*+j+;
colum.push_back(dot);
dot.c=+i*+k;
colum.push_back(dot);
dot.c=+j*+k;
colum.push_back(dot);
dot.c=+(i/*+j/)*+k;
colum.push_back(dot);
Link.addRow(n,colum);
}
} } }
Link.dfs();
for(int i=; i<;i++)
for(int j=; j<; j++)
printf("%d",Link.ans[i][j]);
puts("");
}
return ;
}

poj3074 DLX精确覆盖的更多相关文章

  1. 【转】DLX 精确覆盖 重复覆盖

    问题描述: 给定一个n*m的矩阵,有些位置为1,有些位置为0.如果G[i][j]==1则说明i行可以覆盖j列. Problem: 1)选定最少的行,使得每列有且仅有一个1. 2)选定最少的行,使得每列 ...

  2. POJ 3076 Sudoku DLX精确覆盖

    DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepte ...

  3. (简单) POJ 3074 Sudoku, DLX+精确覆盖。

    Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgr ...

  4. (简单) HUST 1017 Exact cover , DLX+精确覆盖。

    Description There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...

  5. DLX精确覆盖与重复覆盖模板题

    hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms ...

  6. POJ 3074 Sudoku DLX精确覆盖

    DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: ...

  7. zoj 3209.Treasure Map(DLX精确覆盖)

    直接精确覆盖 开始逐行添加超时了,换成了单点添加 #include <iostream> #include <cstring> #include <cstdio> ...

  8. [DLX精确覆盖] hdu 1603 A Puzzling Problem

    题意: 给你n块碎片,这些碎片不能旋转.翻折. 问你能不能用当中的某些块拼出4*4的正方形. 思路: 精确覆盖裸题了 建图就是看看每一个碎片在4*4中能放哪些位置,这个就作为行. 列就是4*4=16个 ...

  9. HUST 1017 Exact cover(DLX精确覆盖)

    Description There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...

随机推荐

  1. 转:Java 异常结构体系

    原文地址:Java 异常结构体系 保存一份资料 前几天在参加网易和360公司的在线考试的时候,都出了一道关于java中异常类的多项选择题.这几天翻看了相关书籍和网上一些资料,结合自己的理解与思考,将自 ...

  2. 内部排序->归并排序->2-路归并排序

    文字描述 假设初始序列有n个记录,则可看成是n个有序的字序列,每个字序列的长度为1,然后两两归并,得到[n/2]个长度为2或1的有序子序列:再两两归并,…, 如此重复,直到得到一个长度为n的有序序列为 ...

  3. shiro默认过滤器

  4. linux配置IP访问权限

    允许访问vi /etc/hosts.allow添加(可以添加多行,其中“:allow”可以省率)sshd:192.168.81.*:allow                     #表示192.1 ...

  5. 洛谷P2329 栅栏 [SCOI2005] 搜索

    正解:搜索 解题报告: 先放下传送门! 首先说下爆搜趴,就直接枚每个需求是否被满足以及如果满足切哪个板子,随便加个最优性剪枝,似乎是有80pts 然后思考优化 首先显然尽量满足需求比较小的,显然如果能 ...

  6. 【数据可视化-pyecharts】pyecharts快速入门

    pyecharts快速开始 首先开始来绘制你的第一个图表 from pyecharts import Bar bar = Bar("我的第一个图表", "这里是副标题&q ...

  7. mvn install package区别

    package是把jar打到本项目的target下,而install时把target下的jar安装到本地仓库,供其他项目使用

  8. 8.0-uC/OS-III单任务应用

    1.单任务应用 app.c文件: (1).APP_CFG.H 是用于配置的头文件.例如, APP_CFG.H 中包含的#define常量确定了任务优先级,堆栈大小,以及其他特性. BSP.H 是 BS ...

  9. state访问状态对象

    状态对象赋值给内部对象,也就是把stroe.js中的值,赋值给我们模板里data中的值.我们有三种赋值方式: 1.通过computed的计算属性直接赋值 Count.vue {count} <s ...

  10. centos 安装 pcre

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/luozhonghua2014/article/details/37054235 #rpm -qa | ...