某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄
膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建
立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个L*L的正方形的边要求平行与坐标轴,一个点如果在
正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求L最小值。
标签:;; min end code stdio.h color 坐标轴 soft mic
一行,输出最小的L值。
100%的数据,N<=20000
题解
每次对于一些点,我们把它们用一个最小的长方形框起来,把正方形放在四角之一
然后就产生了一个子问题,显然这样做是最优的
二分即可
#include<stdio.h> #include<iostream> #define inf 1000000000 #define il inline using namespace std; const int N=30001; struct P{int x,y;} a[N]; int n,chk[N]; il void cover(int d,int u,int l,int r,int k){ for(int i=1;i<=n;i++) if(chk[i]==0){ if(l<=a[i].x&&a[i].x<=r&&d<=a[i].y&&a[i].y<=u){ chk[i]=k; } } } il void uncover(int k){ for(int i=1;i<=n;i++) if(chk[i]==k){ chk[i]=0; } } il bool fulfill(){ for(int i=1;i<=n;i++) if(chk[i]==0) return 0; return 1; } il int dfs(int k,int lim){ if(fulfill()) return true; if(k==4) return false; int u=-inf,d=inf,l=inf,r=-inf,flag=0; for(int i=1;i<=n;i++){ if(chk[i]==0){ u=max(u,a[i].y); d=min(d,a[i].y); l=min(l,a[i].x); r=max(r,a[i].x); } } /*cout<<k<<" "<<lim<<endl; for(int i=1;i<=n;i++) cout<<chk[i]<<" "; cout<<endl; cout<<l<<" "<<r<<" "<<d<<" "<<u<<endl; system("pause");*/ cover(d,d+lim,l,l+lim,k); if(dfs(k+1,lim)) flag=1; uncover(k); cover(d,d+lim,r-lim,r,k); if(dfs(k+1,lim)) flag=1; uncover(k); cover(u-lim,u,r-lim,r,k); if(dfs(k+1,lim)) flag=1; uncover(k); cover(u-lim,u,l,l+lim,k); if(dfs(k+1,lim)) flag=1; uncover(k); return flag; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y); int l=0,r=inf,mid; while(l<r){ mid=(l+r)/2; if(dfs(1,mid)) r=mid; else l=mid+1; } cout<<r; return 0; }
标签:;; min end code stdio.h color 坐标轴 soft mic
原文地址:http://www.cnblogs.com/ExiledPoet/p/6115106.html