poj3074 DLX精确覆盖
题意:解数独
分析:
完整的数独有四个充要条件:
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精确覆盖的更多相关文章
- 【转】DLX 精确覆盖 重复覆盖
问题描述: 给定一个n*m的矩阵,有些位置为1,有些位置为0.如果G[i][j]==1则说明i行可以覆盖j列. Problem: 1)选定最少的行,使得每列有且仅有一个1. 2)选定最少的行,使得每列 ...
- POJ 3076 Sudoku DLX精确覆盖
DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 4416 Accepte ...
- (简单) POJ 3074 Sudoku, DLX+精确覆盖。
Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgr ...
- (简单) 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 ...
- DLX精确覆盖与重复覆盖模板题
hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms ...
- POJ 3074 Sudoku DLX精确覆盖
DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8336 Accepted: ...
- zoj 3209.Treasure Map(DLX精确覆盖)
直接精确覆盖 开始逐行添加超时了,换成了单点添加 #include <iostream> #include <cstring> #include <cstdio> ...
- [DLX精确覆盖] hdu 1603 A Puzzling Problem
题意: 给你n块碎片,这些碎片不能旋转.翻折. 问你能不能用当中的某些块拼出4*4的正方形. 思路: 精确覆盖裸题了 建图就是看看每一个碎片在4*4中能放哪些位置,这个就作为行. 列就是4*4=16个 ...
- 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 ...
随机推荐
- 20165317 学习基础和C语言基础调查
学习基础和C语言基础调查 关于优势技能 说来惭愧,读书多年,爱好不少,但是真的能拿的出手的.能被叫做特长的不多.至今,能在同龄人中处于较领先位置的也只有从四年级开始练起的乒乓球.记得开始练习乒乓球是从 ...
- Excel--数据透视图
原文:https://ke.qq.com/course/289406 1.数据源注意项 2. 3.选中数据源操作 任意选中数据源表格中的单元格(有值得单元格),插入数据透视表 默认数据源区域就是整个表 ...
- Django实现邮件发送功能
首先申请邮箱并在设置中申请到授权码,授权码的目的仅仅是让你有权限发邮件,但是不能登录到邮箱进行修改,发送邮件时,可以代替密码 1,配置文件settings.py #邮件服务配置文件 EMAIL_USE ...
- 洛谷P3724 大佬 [AH2017/HNOI2017] dp+bfs
正解:dp+bfs 解题报告: 传送门! 这题看起来很复杂的样子其实真的很复杂 但是仔细看一下题目,会发现其实操作只有两个目的嘛,一个是保证自己不死,一个是让对手减血 而且保证自己不死只有一种操作 而 ...
- 【Python爬虫】Requests库的基本使用
Requests库的基本使用 阅读目录 基本的GET请求 带参数的GET请求 解析Json 获取二进制数据 添加headers 基本的POST请求 response属性 文件上传 获取cookie 会 ...
- MSSQL2008 部署及开启远程连接
最近不少用户在windows2003 server 32位操作系统上安装SQL Server2008总是失败,出现大量错误.今天经过通过我反复测试安装,找出了一个便捷的安装方法,节省大家宝贵时间,具体 ...
- 前端 HTML body标签相关内容 常用标签 表单标签 form里面的 label标签介绍
定义:<label> 标签为 input 元素定义标注(标记). label标签功能:关联input标签文本与表达元素,点击input标签文本时,如同点击表单元素一样. label标签是行 ...
- CentOS 7.2编译安装nginx1.10.3+MySQL5.5.38+PHP5.5.38
1.关闭firewallad 关闭防火墙 systemctl stop firewalld.service 禁止firewall开机启动 systemctl disable firewalld.ser ...
- UIDatePicker封装
#import <UIKit/UIKit.h> #import <objc/runtime.h> @protocol datePickerViewDelegate <NS ...
- [vue]webpack使用样式
webpack: 使用自己写样式 main.js导入全局生效 import Vue from 'vue' import App from './App.vue' import './index.css ...