码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1052 覆盖问题 二分答案 dfs

时间:2017-09-22 17:43:57      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:geo   closed   str   cst   ons   play   namespace   turn   华丽   

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1052

题意:找到一个最小边长,使得以此为边长$3$个正方形可以覆盖平面上给定的一些点。

华丽爆零……

首先看到最小果断想二分答案……

然后我们证明一个东西……

首先,根据鸽巢原理,$3$个正方形覆盖由所有点构成的最小矩形一定有一个正方形是压着至少两条边的……

然后不外乎两种情况……

1、压的是对边,那么每个都在压对边,有一个正方形会压到三条边,就会压到一个角……

2、压的是邻边,一定会压到一个角……

那么方案就出来了……对于每个正方形,枚举压到了哪个角然后暴力排除每一个被覆盖的点……之后递归搜索新的矩形并继续……

问题得解……

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=(int)1e6+5;
 7 int x[maxn],y[maxn],n,ax[4],ay[4],ajia[4],ajian[4];bool vis[maxn],now[4][maxn];int titai[3]={0,1,-1};
 8 bool dfs(int num,int val)
 9 {
10     if(num>3)
11     {
12         for(int i=1;i<=n;i++)
13             if(!vis[i])return 0;
14         return 1;
15     }
16     int maxx=-2147483647,minx=2147483647,maxy=-2147483647,miny=2147483647;
17     for(int i=1;i<=n;i++)
18         if(!vis[i])maxx=max(maxx,x[i]),minx=min(minx,x[i]),maxy=max(maxy,y[i]),miny=min(miny,y[i]);
19     if(max(maxx-minx,maxy-miny)<=val)return 1;
20     else if(num==3)return 0;
21     for(int i=1;i<=2;i++)
22         for(int j=1;j<=2;j++)
23         {
24             ajia[num]=titai[i],ajian[num]=titai[j];
25             if(ajia[num]==1&&ajian[num]==1)ax[num]=minx,ay[num]=miny;
26             else if(ajia[num]==1&&ajian[num]==-1)ax[num]=minx,ay[num]=maxy;
27             else if(ajia[num]==-1&&ajian[num]==1)ax[num]=maxx,ay[num]=miny;
28             else if(ajia[num]==-1&&ajian[num]==-1)ax[num]=maxx,ay[num]=maxy;
29             for(int i=1;i<=n;i++)
30                 if(!vis[i]&&((ajia[num]==1&&ajian[num]==1&&ax[num]<=x[i]&&ay[num]<=y[i]&&ax[num]+val>=x[i]&&ay[num]+val>=y[i])||(ajia[num]==1&&ajian[num]==-1&&ax[num]<=x[i]&&ay[num]>=y[i]&&ax[num]+val>=x[i]&&ay[num]-val<=y[i])||(ajian[num]==1&&ajia[num]==-1&&ay[num]<=y[i]&&ax[num]>=x[i]&&ay[num]+val>=y[i]&&ax[num]-val<=x[i])||(ajian[num]==-1&&ajia[num]==-1&&ay[num]>=y[i]&&ax[num]>=x[i]&&ay[num]-val<=y[i]&&ax[num]-val<=x[i])))vis[i]=now[num][i]=1;
31             int t=dfs(num+1,val);
32             for(int i=1;i<=n;i++)if(now[num][i])vis[i]=now[num][i]=0;
33             if(t)return 1;
34         }
35     return 0;
36 }
37 bool check(int val)
38 {
39     return dfs(1,val);
40 }
41 int haha()
42 {
43     scanf("%d",&n);int maxx=-2147483647,minx=2147483647,maxy=-2147483647,miny=2147483647;
44     for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]),maxx=max(maxx,x[i]),minx=min(minx,x[i]),maxy=max(maxy,y[i]),miny=min(miny,y[i]);
45     int l=1,r=max(maxx-minx,maxy-miny),mid;
46     while(l<=r)
47     {
48         mid=(l+r)>>1;
49         if(check(mid))r=mid-1;
50         else l=mid+1;
51     }
52     printf("%d\n",l);
53 }
54 int sb=haha();
55 int main(){;}
bzoj1052

 

bzoj1052 覆盖问题 二分答案 dfs

标签:geo   closed   str   cst   ons   play   namespace   turn   华丽   

原文地址:http://www.cnblogs.com/Loser-of-Life/p/7575669.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!