题意 :  给你一个大小为 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 精确覆盖 )的更多相关文章

  1. ZOJ 3209 Treasure Map (Dancing Links)

    Treasure Map Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit S ...

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

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

  3. ZOJ3209 Treasure Map —— Danc Links 精确覆盖

    题目链接:https://vjudge.net/problem/ZOJ-3209 Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 ...

  4. ZOJ 3209 Treasure Map (Dancing Links)

    Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of ...

  5. ZOJ 3209 Treasure Map(精确覆盖)

    Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of ...

  6. (简单) ZOJ 3209 Treasure Map , DLX+精确覆盖。

    Description Your boss once had got many copies of a treasure map. Unfortunately, all the copies are ...

  7. ZOJ 3209 Treasure Map 精确覆盖

    题目链接 精确覆盖的模板题, 把每一个格子当成一列就可以. S忘记初始化TLE N次, 哭晕在厕所...... #include<bits/stdc++.h> using namespac ...

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

    题意:一个 n x m 的矩形(1 <= n, m <= 30),现给出这个矩形中 p 个(1 <= p <= 500)子矩形的左下角与右下角坐标,问最少用多少个子矩形能够恰好 ...

  9. hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)

    hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...

随机推荐

  1. RPC——笔记

    整理的笔记来源:https://mp.weixin.qq.com/s/JkXrPcuKtE2qYgmDcH2uww RPC(远程过程调用): RPC是:一个计算机通信协议. 调用过程:计算机 A 上的 ...

  2. Thread stack overrun

    ERROR 1436 (HY000): Thread stack overrun:  6448 bytes used of a 131072 byte stac k, and 128000 bytes ...

  3. ios 布局 素材 待整理

    https://www.cnblogs.com/fxwl/p/5961372.html div区域 8.盒子模型的相关属性 margin(外边距/边界) border(边框) padding(内边距/ ...

  4. CAD得到所有实体2

    主要用到函数说明: IMxDrawSelectionSet::Select2 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARI ...

  5. MySQL基础:show命令总结

    show命令 show命令可以提供关于数据库.表.列,或关于服务器的状态信息. 总结 # 显示二进制文件以及文件大小(需要开启二进制日志记录功能) SHOW {BINARY | MASTER} LOG ...

  6. Eclipse添加背景图片

    ①前言:我本人是一个比较喜新厌旧的人,经常换头像,背景图片之类的,喜欢折腾,哈哈,所以每次都上网查怎么修改背景图片比较麻烦,这里也记录一下怎么修改. ②原文链接:https://yq.aliyun.c ...

  7. Missing message for key "xxx" in bundle "(default bundle)" for locale zh_CN

    参考文章http://programmerslounge.blogspot.com/2013/03/error-missing-message-for-key.html 错误的struts-confi ...

  8. pandas 处理 excel

    先写下来,以免后续忘记,有很多都是之前用过的, 依旧忘!!! 嘤嘤嘤 data_file = pandas.read_excel('/imporExcel/2017_7_7.xlsx',sep = ' ...

  9. LINUX-YUM 软件包升级器 - (Fedora, RedHat及类似系统)

    yum install package_name 下载并安装一个rpm包 yum localinstall package_name.rpm 将安装一个rpm包,使用你自己的软件仓库为你解决所有依赖关 ...

  10. Literature Review on Tidal Turbine

    source: scopus , SCIE keywords in tilte: tidal turbine Software: Bibliometrix