ZOJ 3209 Treasure Map (Dancing Links 精确覆盖 )
题意 : 给你一个大小为 n * m 的矩形 , 坐标是( 0 , 0 ) ~ ( n , m ) 。然后给你 p 个小矩形 。 坐标是( x1 , y1 ) ~ ( x2 , y2 ) , 你选择最小的几个矩形 , 使得这些矩形能够覆盖整个矩形 。 而且互相不会重叠 。( n , m <= 30 )
思路 : Dancing Links 的精确覆盖问题 。
我们将 n * m 的矩形分成 n * m 个小正方形 ,那么我们仅仅要保证每一个小正方形被覆盖且仅仅被覆盖一次就可以 。
那么列表示每一个小正方形 。 行表示你选择的矩形 。 假设选择这个矩形能够覆盖某个小正方形 。 则相应的格子是1 , 否则相应的格子是 0
最多有 30 * 30 = 900 列 ,最多有 500 行
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std; const int maxn = 900 + 10 ;
const int maxr = 500 + 10 ;
const int maxnode = 500 * 900 + maxr + 10 ; #define FOR( i , A , s ) for( int i = A[s] ; i != s ; i = A[i] ) struct DLX{
// maxn 列数 , maxnode 总节点数 , maxr 行数
int n , sz ;
int S[maxn] ; int row[maxnode] , col[maxnode] ;
int L[maxnode] , R[maxnode] , U[maxnode] , D[maxnode] ;
int H[maxr] ; int ansd , ans[maxr] ; void init( int N ) {
n = N ;
// 第一行的虚拟结点
for( int i = 0 ; i <= n ; i ++ ) {
U[i] = D[i] = i ;
L[i] = i - 1 ;
R[i] = i + 1 ;
}
R[n] = 0 ; L[0] = n ;
sz = n + 1 ;
// 每一列的个数
memset( S , 0 , sizeof(S) ) ;
// H[i] = -1 表示这一行还没有 1
// 否则表示第一个 1 的 sz 是多少
memset( H , -1 , sizeof(H)) ;
} // 在第r行第c列加入一个1
void Link( int r , int c ) {
row[sz] = r ;
col[sz] = c ;
S[c] ++ ; D[sz] = c ; U[sz] = U[c] ;
D[U[c]] = sz ; U[c] = sz ; if( H[r] < 0 ) { H[r] = L[sz] = R[sz] = sz ; }
else{
R[sz] = H[r] ;
L[sz] = L[H[r]] ;
R[L[sz]] = sz ;
L[R[sz]] = sz ;
} sz ++ ; } // 删除 第 c 列
void remove ( int c ) {
// 删除虚拟结点中的 c 列
L[R[c]] = L[c] ;
R[L[c]] = R[c] ;
// 从 c 列向下遍历
FOR( i , D , c ) {
// 删除遍历到的行
FOR( j , R , i ) {
D[U[j]] = D[j] ;
U[D[j]] = U[j] ;
-- S[col[j]] ;
}
}
} // 恢复第 c 列
void restore( int c ) {
FOR( i , U , c ) {
FOR( j , L , i ) {
++S[col[j]] ;
U[D[j]] = D[U[j]] = j ;
}
}
L[R[c]] = R[L[c]] = c ;
} void dfs( int d ) { // 剪枝
if( d >= best ) {
return ;
} // R[0] = 0 表示找到一个可行解
if( R[0] == 0 ) {
best = d ;
return ;
} // 找到 s 最小的列 , 加快搜索的速度
int c = R[0] ;
FOR( i , R , 0 )
if( S[i] < S[c] ) c = i ; // 删除第 c 列
remove( c ) ; // 遍历选中列中有1的行
FOR( i , D , c ) {
ans[d] = row[i] ;
// 删除选中行中有1的列
FOR( j , R , i ) {
remove( col[j] ) ;
}
dfs( d + 1 ) ;
// 回复删除掉的列
FOR( j , L , i ) {
restore( col[j] ) ;
}
}
restore( c ) ;
} int solve() {
best = INF ;
dfs( 0 ) ;
if( best == INF )
return -1 ;
else
return best ;
}
int best ;
const static int INF = 0x3f3f3f3f ;
} dlx ; int main(){
int cas ;
scanf( "%d" , &cas ) ;
while( cas -- ) {
int n , m , p ;
scanf( "%d%d%d" , &n , &m , &p ) ;
dlx.init( n * m ) ;
for( int i = 1 ; i <= p ; i ++ ) {
int x1 , y1 , x2 , y2 ;
scanf( "%d%d%d%d" , &x1 , &y1 , &x2 , &y2 ) ;
for( int x = x1 ; x < x2 ; x ++ ) {
for( int y = y1 ; y < y2 ; y ++ ) {
dlx.Link( i , x * m + y + 1 ) ;
}
}
}
printf( "%d\n" , dlx.solve() ) ;
}
return 0 ;
}
ZOJ 3209 Treasure Map (Dancing Links 精确覆盖 )的更多相关文章
- ZOJ 3209 Treasure Map (Dancing Links)
Treasure Map Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Submit S ...
- zoj 3209.Treasure Map(DLX精确覆盖)
直接精确覆盖 开始逐行添加超时了,换成了单点添加 #include <iostream> #include <cstring> #include <cstdio> ...
- ZOJ3209 Treasure Map —— Danc Links 精确覆盖
题目链接:https://vjudge.net/problem/ZOJ-3209 Treasure Map Time Limit: 2 Seconds Memory Limit: 32768 ...
- ZOJ 3209 Treasure Map (Dancing Links)
Treasure Map Time Limit: 2 Seconds Memory Limit: 32768 KB Your boss once had got many copies of ...
- ZOJ 3209 Treasure Map(精确覆盖)
Treasure Map Time Limit: 2 Seconds Memory Limit: 32768 KB Your boss once had got many copies of ...
- (简单) ZOJ 3209 Treasure Map , DLX+精确覆盖。
Description Your boss once had got many copies of a treasure map. Unfortunately, all the copies are ...
- ZOJ 3209 Treasure Map 精确覆盖
题目链接 精确覆盖的模板题, 把每一个格子当成一列就可以. S忘记初始化TLE N次, 哭晕在厕所...... #include<bits/stdc++.h> using namespac ...
- zoj - 3209 - Treasure Map(精确覆盖DLX)
题意:一个 n x m 的矩形(1 <= n, m <= 30),现给出这个矩形中 p 个(1 <= p <= 500)子矩形的左下角与右下角坐标,问最少用多少个子矩形能够恰好 ...
- hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)
hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...
随机推荐
- js中取整数的方法
1.取整的方法 Math.floor( ) Math 对象的方法--取比当前数值小的最大整数(下取整). Math.ceil( ) Math对象的方法--取比当前数值大的最小整数(上取整). Math ...
- 左耳听风 ARTS Week 001
要求:1.每周至少做一个 leetcode 的算法题 2.阅读并点评至少一篇英文技术文章 3.学习至少一个技术技巧 4.分享一篇有观点和思考的技术文章 1.每周至少做一个 leetcode 的算法题 ...
- postgreSQL在Centos6下编译安装
1.准备安装源 下载地址:https://www.postgresql.org/ftp/source/ 下载并解压. 2.软件编译安装 配置.检查安装环境 ./configure --prefix=/ ...
- Sturts2几个常用内建拦截器的介绍
Sturts2几个常用内建拦截器的介绍:1)conversation:这是一个处理类型转换错误的拦截器,它负责将类型转换错误从ActionContext中取出,并转换成Action的FieldErro ...
- CAD使用SetXData写数据(com接口)
主要用到函数说明: MxDrawEntity::SetXData 设置实体的扩展数据,详细说明如下: 参数 说明 [in] IMxDrawResbuf* pXData 扩展数据链表 c#代码实现如下: ...
- <东方梦符祭> N1无尽30波终于通了
嘛也算是第一次通关 纪念一下 阵容:xjb搭的杂牌队 主C:古明绝恋 露米娅(真·R卡战神)比那名居天子 斯卡雷特 控制:琪露诺 蕾蒂 灵梦 挂件:小伞 纳兹琳 古明地觉 永江依玖 第一发就直接抽到了 ...
- 在添加新内容时,creatat没有数据
首先找到controller中的add方法,然后是执行了Service.insert()方法 然后找到service对应的impl方法, impl方法中的 public void insert(Cus ...
- 还没更换RubyGems镜像?
相信用过Ruby的人都知道 gem install 命令,但是在国内该命令安装的速度甚是不稳定(你懂的),导致尝试数次便是等待数时,记得之前在安装redmine的时候便是如此,之前不懂什么意思,还以为 ...
- [Java小程序]聊天室——Socket和ServerSocket的使用
这段小代码是因为担任Java助教给刚学习Java的本科大二的小学弟小学妹们指导,他们的实验作业就是编写一个Java聊天室客户端和服务器,为了避免出纰漏,自己事先写了一下. 客户端Ui代码: packa ...
- 关于SPFA的双端队列优化
7.11 Update 我做题的时候发现这样写会RE 因为在使用双端队列优化SPFA的时候 在将一个点加入队列的时候,如果队列已经空了 那么一旦出现dis[Q.front()]就会RE 可以这样修改 ...