标签:namespace printf inline typedef ref ret space haoi2007 color
首先可以想到二分答案,然后考虑判断
注意到所有点的外包矩形的四条边一定要被覆盖到,而正方形只有 $3$ 个,所以一定有一个正方形在角落
考虑爆搜,枚举正方形在当前外包矩形的那个角,然后对剩下的点的外包矩形继续这样搞
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) f=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=1e5+7,INF=2e9; int n,px[N],py[N],ans; int vis[N]; inline void Cover(int xa,int ya,int xb,int yb,int p) { for(int i=1;i<=n;i++) if(!vis[i]&&px[i]>=xa&&px[i]<=xb&&py[i]>=ya&&py[i]<=yb) vis[i]=p; } inline void Uncover(int p) { for(int i=1;i<=n;i++) if(vis[i]==p) vis[i]=0; } inline bool dfs(int p,int L) { int lx=INF,rx=-INF,ly=INF,ry=-INF; for(int i=1;i<=n;i++) { if(vis[i]) continue; lx=min(lx,px[i]); rx=max(rx,px[i]); ly=min(ly,py[i]); ry=max(ry,py[i]); } if(max(rx-lx,ry-ly)<=L) return 1; if(p==3) return 0; Cover(lx,ly,lx+L,ly+L,p); if(dfs(p+1,L)) return 1; Uncover(p); Cover(lx,ry-L,lx+L,ry,p); if(dfs(p+1,L)) return 1; Uncover(p); Cover(rx-L,ry-L,rx,ry,p); if(dfs(p+1,L)) return 1; Uncover(p); Cover(rx-L,ly,rx,ly+L,p); if(dfs(p+1,L)) return 1; Uncover(p); return 0; } bool check(int mid) { for(int i=1;i<=n;i++) vis[i]=0; return dfs(1,mid); } int main() { n=read(); for(int i=1;i<=n;i++) px[i]=read(),py[i]=read(); int L=0,R=INF; while(L<=R) { int mid=L+R>>1; if(check(mid)) ans=mid,R=mid-1; else L=mid+1; } printf("%d\n",ans); return 0; }
标签:namespace printf inline typedef ref ret space haoi2007 color
原文地址:https://www.cnblogs.com/LLTYYC/p/11450825.html