题意:解数独

分析:

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

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. 20165317 学习基础和C语言基础调查

    学习基础和C语言基础调查 关于优势技能 说来惭愧,读书多年,爱好不少,但是真的能拿的出手的.能被叫做特长的不多.至今,能在同龄人中处于较领先位置的也只有从四年级开始练起的乒乓球.记得开始练习乒乓球是从 ...

  2. Excel--数据透视图

    原文:https://ke.qq.com/course/289406 1.数据源注意项 2. 3.选中数据源操作 任意选中数据源表格中的单元格(有值得单元格),插入数据透视表 默认数据源区域就是整个表 ...

  3. Django实现邮件发送功能

    首先申请邮箱并在设置中申请到授权码,授权码的目的仅仅是让你有权限发邮件,但是不能登录到邮箱进行修改,发送邮件时,可以代替密码 1,配置文件settings.py #邮件服务配置文件 EMAIL_USE ...

  4. 洛谷P3724 大佬 [AH2017/HNOI2017] dp+bfs

    正解:dp+bfs 解题报告: 传送门! 这题看起来很复杂的样子其实真的很复杂 但是仔细看一下题目,会发现其实操作只有两个目的嘛,一个是保证自己不死,一个是让对手减血 而且保证自己不死只有一种操作 而 ...

  5. 【Python爬虫】Requests库的基本使用

    Requests库的基本使用 阅读目录 基本的GET请求 带参数的GET请求 解析Json 获取二进制数据 添加headers 基本的POST请求 response属性 文件上传 获取cookie 会 ...

  6. MSSQL2008 部署及开启远程连接

    最近不少用户在windows2003 server 32位操作系统上安装SQL Server2008总是失败,出现大量错误.今天经过通过我反复测试安装,找出了一个便捷的安装方法,节省大家宝贵时间,具体 ...

  7. 前端 HTML body标签相关内容 常用标签 表单标签 form里面的 label标签介绍

    定义:<label> 标签为 input 元素定义标注(标记). label标签功能:关联input标签文本与表达元素,点击input标签文本时,如同点击表单元素一样. label标签是行 ...

  8. CentOS 7.2编译安装nginx1.10.3+MySQL5.5.38+PHP5.5.38

    1.关闭firewallad 关闭防火墙 systemctl stop firewalld.service 禁止firewall开机启动 systemctl disable firewalld.ser ...

  9. UIDatePicker封装

    #import <UIKit/UIKit.h> #import <objc/runtime.h> @protocol datePickerViewDelegate <NS ...

  10. [vue]webpack使用样式

    webpack: 使用自己写样式 main.js导入全局生效 import Vue from 'vue' import App from './App.vue' import './index.css ...