【BZOJ 1052】 1052: [HAOI2007]覆盖问题 (乱搞)

1052: [HAOI2007]覆盖问题

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

Source

 

 

【分析】

  为什么黄学长称之为贪心。。?不懂。。

  首先我们用一个最小的矩形把所有点框住(这个很容易求吧?),

  如果答案的正方形边长等于这个矩形的宽,那么肯定有两个正方形是推到两边的,就是至少有一个正方形的顶点是矩形的顶点。

  如果正方形边长小于宽,因为矩形每条边至少有一个点,所以一定有一个正方形覆盖了矩形两条边,那么这个至少也有一个正方形的顶点是矩形的顶点。

  大于宽就不用说了吧?

  那么我们先二分答案,然后就枚举矩形的四个角,把覆盖的点删掉,递归做子问题就可以了。

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 20010
 8 #define INF 0xfffffff
 9 
10 int mymin(int x,int y) {return x<y?x:y;}
11 int mymax(int x,int y) {return x>y?x:y;}
12 
13 struct node
14 {
15     int x,y;
16     int p;
17 }t[Maxn];
18 
19 int n,tot;
20 
21 void change(int x,int y,int nw,int L)
22 {
23     for(int i=1;i<=n;i++) if(t[i].x>=x&&t[i].y>=y&&t[i].p==0)
24     {
25         if(t[i].x-x>L||t[i].y-y>L) continue;
26         t[i].p=nw;tot--;
27     }
28 }
29 
30 void change2(int nw)
31 {
32     for(int i=1;i<=n;i++) if(t[i].p==nw) 
33     {
34         t[i].p=0;
35         tot++;
36     }
37 }
38 
39 bool check(int L,int nw)
40 {
41     if(tot==0) return 1;
42     int x1=INF,x2=-INF,y1=INF,y2=-INF;
43     for(int i=1;i<=n;i++) if(t[i].p==0)
44     {
45         x1=mymin(x1,t[i].x);x2=mymax(x2,t[i].x);
46         y1=mymin(y1,t[i].y);y2=mymax(y2,t[i].y);
47     }
48     if(nw==1) return mymax(x2-x1,y2-y1)<=L;
49     int nx,ny;
50     bool ok=0;
51     nx=x1,ny=y1;change(nx,ny,nw,L);
52     if(check(L,nw-1)) ok=1;change2(nw);
53     if(ok) return 1;
54     
55     nx=x1,ny=y2-L;change(nx,ny,nw,L);
56     if(check(L,nw-1)) ok=1;change2(nw);
57     if(ok) return 1;
58     
59     nx=x2-L,ny=y1;change(nx,ny,nw,L);
60     if(check(L,nw-1)) ok=1;change2(nw);
61     if(ok) return 1;
62     
63     nx=x2-L,ny=y2-L;change(nx,ny,nw,L);
64     if(check(L,nw-1)) ok=1;change2(nw);
65     if(ok) return 1;
66     return 0;
67 }
68 
69 int main()
70 {
71     scanf("%d",&n);
72     for(int i=1;i<=n;i++)
73     {
74         scanf("%d%d",&t[i].x,&t[i].y);
75         t[i].p=0;
76     }
77     int l=1,r=INF;
78         tot=n;
79     while(l<r)
80     {
81         int mid=(l+r)>>1;
82         if(check(mid,3)) r=mid;
83         else l=mid+1;
84     }
85     printf("%d\n",l);
86     return 0;
87 }
View Code

 

2017-02-22 14:07:58

posted @ 2017-02-22 14:01  konjak魔芋  阅读(199)  评论(0编辑  收藏  举报