ZOJ 3209 Treasure Map (Dancing Links)

Treasure Map


Time Limit: 2 Seconds
     Memory
Limit: 32768 KB


Your boss once had got many copies of a treasure map. Unfortunately, all the
copies are now broken to many rectangular pieces, and what make it worse, he has
lost some of the pieces. Luckily, it is possible to figure out the position of
each piece in the original map. Now the boss asks you, the talent programmer, to
make a complete treasure map with these pieces. You need to make only one
complete map and it is not necessary to use all the pieces. But remember, pieces
are not allowed to overlap with each other (See sample 2).

Input

The first line of the input contains an
integer T (T <= 500), indicating the number
of cases.

For each case, the first line contains three
integers n m p (1
<= nm <= 30, 1
<= p <= 500), the width and the height of the map, and
the number of pieces. Then p lines follow, each consists of
four
integers x1 y1 x2 y2 (0
<= x1 < x2 <= n, 0
<= y1 < y2 <= m),
where (x1, y1) is the coordinate of the lower-left corner of the rectangular
piece, and (x2, y2) is the coordinate of the upper-right corner in the original
map.

Cases are separated by one blank line.

Output

If you can make a complete map with these pieces, output the least
number of pieces you need to achieve this. If it is impossible to make one
complete map, just output -1.

Sample Input

3
5 5 1
0 0 5 5

5 5 2
0 0 3 5
2 0 5 5

30 30 5
0 0 30 10
0 10 30 20
0 20 30 30
0 0 15 30
15 0 30 30


Sample Output

1
-1
2

Hint

For sample 1, the only piece is a complete map.

For sample 2, the two pieces may overlap with each other, so you can not make
a complete treasure map.

For sample 3, you can make a map by either use the first 3 pieces or the last
2 pieces, and the latter approach one needs less pieces.


Author: HANG,
Hang

Source: The 6th Zhejiang Provincial
Collegiate Programming Contest

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3372

就是简单的精确覆盖问题。

把每个格子当成一个列,要覆盖所有格子。

写一下Dancing Links模板就可以了


  1 /* ***********************************************
2 Author :kuangbin
3 Created Time :2014/5/26 21:50:46
4 File Name :E:\2014ACM\专题学习\DLX\ZOJ3209.cpp
5 ************************************************ */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <iostream>
10 #include <algorithm>
11 #include <vector>
12 #include <queue>
13 #include <set>
14 #include <map>
15 #include <string>
16 #include <math.h>
17 #include <stdlib.h>
18 #include <time.h>
19 using namespace std;
20 const int maxnode = 500010;
21 const int MaxM = 1010;
22 const int MaxN = 510;
23 struct DLX
24 {
25 int n,m,size;
26 int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
27 int H[MaxN],S[MaxM];
28 int ansd;
29 void init(int _n,int _m)
30 {
31 n = _n;
32 m = _m;
33 for(int i = 0;i <= m;i++)
34 {
35 S[i] = 0;
36 U[i] = D[i] = i;
37 L[i] = i-1;
38 R[i] = i+1;
39 }
40 R[m] = 0; L[0] = m;
41 size = m;
42 for(int i = 1;i <= n;i++)
43 H[i] = -1;
44 }
45 void Link(int r,int c)
46 {
47 ++S[Col[++size]=c];
48 Row[size] = r;
49 D[size] = D[c];
50 U[D[c]] = size;
51 U[size] = c;
52 D[c] = size;
53 if(H[r] < 0)H[r] = L[size] = R[size] = size;
54 else
55 {
56 R[size] = R[H[r]];
57 L[R[H[r]]] = size;
58 L[size] = H[r];
59 R[H[r]] = size;
60 }
61 }
62 void remove(int c)
63 {
64 L[R[c]] = L[c]; R[L[c]] = R[c];
65 for(int i = D[c];i != c;i = D[i])
66 for(int j = R[i];j != i;j = R[j])
67 {
68 U[D[j]] = U[j];
69 D[U[j]] = D[j];
70 --S[Col[j]];
71 }
72 }
73 void resume(int c)
74 {
75 for(int i = U[c];i != c;i = U[i])
76 for(int j = L[i];j != i;j = L[j])
77 ++S[Col[U[D[j]]=D[U[j]]=j]];
78 L[R[c]] = R[L[c]] = c;
79 }
80 void Dance(int d)
81 {
82 //剪枝下
83 if(ansd != -1 && ansd <= d)return;
84 if(R[0] == 0)
85 {
86 if(ansd == -1)ansd = d;
87 else if(d < ansd)ansd = d;
88 return;
89 }
90 int c = R[0];
91 for(int i = R[0];i != 0;i = R[i])
92 if(S[i] < S[c])
93 c = i;
94 remove(c);
95 for(int i = D[c];i != c;i = D[i])
96 {
97 for(int j = R[i];j != i;j = R[j])remove(Col[j]);
98 Dance(d+1);
99 for(int j = L[i];j != i;j = L[j])resume(Col[j]);
100 }
101 resume(c);
102 }
103 };
104 DLX g;
105
106 int main()
107 {
108 //freopen("in.txt","r",stdin);
109 //freopen("out.txt","w",stdout);
110 int T;
111 int n,m,p;
112 scanf("%d",&T);
113 while(T--)
114 {
115 scanf("%d%d%d",&n,&m,&p);
116 g.init(p,n*m);
117 int x1,y1,x2,y2;
118 for(int k = 1;k <= p;k++)
119 {
120 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
121 for(int i = x1+1;i <= x2;i++)
122 for(int j = y1+1;j <= y2;j++)
123 g.Link(k,j + (i-1)*m);
124 }
125 g.ansd = -1;
126 g.Dance(0);
127 printf("%d\n",g.ansd);
128 }
129 return 0;
130 }

ZOJ 3209 Treasure Map (Dancing Links),布布扣,bubuko.com

时间: 2024-12-19 10:06:11

ZOJ 3209 Treasure Map (Dancing Links)的相关文章

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 个小正方形 ,那么我们只要保证每个小正方形被覆盖且只被覆盖一次即可 . 那么列表示每个小正

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

题意:一个 n x m 的矩形(1 <= n, m <= 30),现给出这个矩形中 p 个(1 <= p <= 500)子矩形的左下角与右下角坐标,问最少用多少个子矩形可以恰好组成这个 n x m 的大矩形. 题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3372 -->>这是精确覆盖问题,而DLX正是解决精确覆盖问题的有利武器.. 模型转换:将原矩形变成一行,作为 DLX 中的列,表示要

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

直接精确覆盖 开始逐行添加超时了,换成了单点添加 #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <vector> using namespace std; #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i]) #define exp 1e-8 const int MAX =

跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题(转)

跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 转:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合呢?我们采用回溯法 矩阵1: 先假定选择第1行,如下所示: 如上图中所示,红色的那行是选中的一行,这一行中有3个1,分别是第3.5.

【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题

题意:多组数据.每组数据给你几行数,要求选出当中几行,使得每一列都有且仅有一个1,询问是可不可行,或者说能不能找出来. 题解:1.暴搜.2.DLX(Dancing links). 本文写的是DLX. 算法參考白书P406或者http://www.cnblogs.com/grenet/p/3145800.html 我说一些仔细的东西,就是删除操作的形状是 | --|---- --|---- --|---- 被删除的点们之间的联系不用删,能够保留.准确地说它并非删去了这些点,而是删去这个形. 并且恢

[ACM] ZOJ 3209 Treasure Map ( Dancing Links 精确覆盖,矩形覆盖)

Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of a treasure map. Unfortunately, all the copies are now broken to many rectangular pieces, and what make it worse, he has lost some of the pieces. Luck

ZOJ 3209 Treasure Map dancing links

分析:dancing links 裸题 ,只要把每个格子看成一列就好了,精确不重复覆盖问题 #include<cstdio> #include<cstring> #include<queue> #include<cstdlib> #include<algorithm> #include<vector> #include<cmath> using namespace std; typedef long long LL; co

ZOJ 3209 Treasure Map(舞蹈链)

题目链接:[kuangbin带你飞]专题三 Dancing Links B - Treasure Map 题意 给一矩形和k个小矩形,问选取最小数量为多少的小矩形可以对大矩形进行精确覆盖. 思路 仍然是个模版题,把二维的n*m的大矩形看作是一维的n*m的一条线.k个小矩形同理,那么就转化成01矩阵精确覆盖的问题了. 代码 #include <iostream> #include <algorithm> #include <cstring> #include <cs

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

Description Your boss once had got many copies of a treasure map. Unfortunately, all the copies are now broken to many rectangular pieces, and what make it worse, he has lost some of the pieces. Luckily, it is possible to figure out the position of e