bzoj1052 9.20考试 第二题 覆盖问题

Posted Hzoi_joker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1052 9.20考试 第二题 覆盖问题相关的知识,希望对你有一定的参考价值。

1052: [HAOI2007]覆盖问题

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2004  Solved: 937
[Submit][Status][Discuss]

Description

  某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄
膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建
立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个L*L的正方形的边要求平行与坐标轴,一个点如果在
正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求L最小值。

Input

  第一行有一个正整数N,表示有多少棵树。接下来有N行,第i+1行有2个整数Xi,Yi,表示第i棵树的坐标,保证
不会有2个树的坐标相同。

Output

  一行,输出最小的L值。

Sample Input

4
0 1
0 -1
1 0
-1 0

Sample Output

1

HINT

 

100%的数据,N<=20000

  

  这道题当时一看还以为是一道几何题,就先放着最后打然后就华丽丽的爆零了。

  最后正解并不是我当初第一反应的几何,但确实是我当时第二反应——二分答案,exciting……

  我们可以通过一个无法用语言描述的证明可知至少有一个正方形是位于最小矩形的一个角上的。因为一共就三个正方形,所以我们dfs每个正方形位于当前最小矩形的四个角的情况就好了,那么时间复杂度就是O(log (2*10^9)*n*64)轻松搞掉。

技术分享
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<vector>
10 #define N 20005
11 using namespace std;
12 int n,xx,nx,xy,ny;
13 bool fw[N];
14 struct no
15 {
16     int x,y;
17 }node[N];
18 bool dfs(long long L,int x,int sum)
19 {
20     if(sum==n)return 1;
21     if(x==4)
22         return 0;
23     int xxx=-0x7fffffff,nnx=0x7fffffff,xxy=-0x7fffffff,nny=0x7fffffff;
24     if(x==1)
25         xxx=xx,nnx=nx,xxy=xy,nny=ny;
26     else
27     {
28         for(int i=1;i<=n;i++)
29         {
30             if(fw[i])continue;
31             if(node[i].x>xxx) xxx=node[i].x;
32             if(node[i].x<nnx) nnx=node[i].x;
33             if(node[i].y>xxy) xxy=node[i].y;
34             if(node[i].y<nny) nny=node[i].y;
35         }
36     }
37     bool b[N];
38     int t=sum;
39     memcpy(b,fw,sizeof(fw));
40     for(int i=1;i<=n;i++)
41     {
42         if(!fw[i]&&node[i].x<=nnx+L&&node[i].y<=nny+L)
43             fw[i]=1,t++;
44     }
45     if(dfs(L,x+1,t)) return 1;
46     memcpy(fw,b,sizeof(b));
47     t=sum;
48     for(int i=1;i<=n;i++)
49     {
50         if(!fw[i]&&node[i].x<=nnx+L&&node[i].y>=xxy-L)
51             fw[i]=1,t++;
52     }
53     if(dfs(L,x+1,t)) return 1;
54  
55     memcpy(fw,b,sizeof(b));
56     t=sum;
57     for(int i=1;i<=n;i++)
58     {
59         if(!fw[i]&&node[i].x>=xxx-L&&node[i].y<=nny+L)
60             fw[i]=1,t++;
61     }
62     if(dfs(L,x+1,t)) return 1;
63  
64     t=sum;
65     memcpy(fw,b,sizeof(b));
66     for(int i=1;i<=n;i++)
67     {
68         if(!fw[i]&&node[i].x>=xxx-L&&node[i].y>=xxy-L)
69             fw[i]=1,t++;
70     }
71     if(dfs(L,x+1,t)) return 1;
72     memcpy(fw,b,sizeof(b));
73     return 0;
74 }
75 int main()
76 {
77     scanf("%d",&n);
78     xx=-0x7fffffff,nx=0x7fffffff,ny=0x7fffffff,xy=-0x7fffffff;
79     for(int i=1;i<=n;i++)
80     {
81         scanf("%d%d",&node[i].x,&node[i].y);
82         if(node[i].x>xx) xx=node[i].x;
83         if(node[i].x<nx) nx=node[i].x;
84         if(node[i].y>xy) xy=node[i].y;
85         if(node[i].y<ny) ny=node[i].y;
86         fw[i]=0;
87     }
88     long long li=0,ri=max(xy-ny,xx-nx);
89     while(li<=ri)
90     {
91         long long mid=(li+ri)>>1;
92         memset(fw,0,sizeof(fw));
93         if(dfs(mid,1,0))ri=mid-1;
94         else li=mid+1;
95     }
96     printf("%lld\n",ri+1);
97     return 0;
98 }
View Code

 







以上是关于bzoj1052 9.20考试 第二题 覆盖问题的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2752 9.20考试第三题 高速公路(road)题解

二分判定 覆盖问题 BZOJ 1052

bzoj1052 覆盖问题 二分答案 dfs

二分 贪心覆盖问题 BZOJ1052 HAOI2007

[BZOJ]1052 覆盖问题(HAOI2007)

BZOJ1052[HAOI2007]覆盖问题