bzoj1185【HNOI2007】最小矩形覆盖
来源:互联网 发布:锐捷交换机端口聚合 编辑:程序博客网 时间:2024/05/29 02:54
1185: [HNOI2007]最小矩形覆盖
Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1114 Solved: 505
[Submit][Status][Discuss]
Description
凸包+旋转卡壳
首先有一个结论:矩形一定有一条边在凸包上,否则我们旋转之后一定会得到一个更小的矩形,脑补一下。
然后枚举凸包上的边,用旋转卡壳维护矩形的另外三条边,同时更新答案即可。
#include<iostream>#include<cstdio>#include<cmath>#include<cstdlib>#include<cstring>#include<algorithm>#include<set>#define F(i,j,n) for(int i=j;i<=n;i++)#define D(i,j,n) for(int i=j;i>=n;i--)#define ll long long#define maxn 50005#define eps 1e-8#define inf 1e60using namespace std;int n,top;double mn=inf;struct data{double x,y;friend bool operator ==(data a,data b){return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;}friend bool operator !=(data a,data b){return !(a==b);}friend bool operator <(data a,data b){return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;}friend bool operator >(data a,data b){return !(a==b)&&!(a<b);}friend data operator +(data a,data b){return (data){a.x+b.x,a.y+b.y};}friend data operator -(data a,data b){return (data){a.x-b.x,a.y-b.y};}friend double operator *(data a,data b){return a.x*b.y-a.y*b.x;}//叉积 friend double operator /(data a,data b){return a.x*b.x+a.y*b.y;}//点积 friend data operator *(data a,double b){return (data){a.x*b,a.y*b};}}p[maxn],s[maxn],ans[4];inline double dis(data a,data b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline bool cmp(data a,data b){double t=(a-p[1])*(b-p[1]);if (fabs(t)<eps) return (dis(a,p[1])<dis(b,p[1]));else return t>0;}inline void solve(){F(i,2,n) if (p[i]<p[1]) swap(p[1],p[i]);sort(p+2,p+n+1,cmp);s[++top]=p[1];F(i,2,n){while (top>1&&(p[i]-s[top-1])*(s[top]-s[top-1])>-eps) top--;s[++top]=p[i];}}inline void getans(){int l=1,r=1,p=1;double L,R,D,H;s[0]=s[top];F(i,0,top-1){D=dis(s[i],s[i+1]);while ((s[i+1]-s[i])*(s[p+1]-s[i])-(s[i+1]-s[i])*(s[p]-s[i])>-eps) p=(p+1)%top;while ((s[i+1]-s[i])/(s[r+1]-s[i])-(s[i+1]-s[i])/(s[r]-s[i])>-eps) r=(r+1)%top;if (i==0) l=r;while ((s[i+1]-s[i])/(s[l+1]-s[i])-(s[i+1]-s[i])/(s[l]-s[i])<eps) l=(l+1)%top;L=((s[i+1]-s[i])/(s[l]-s[i]))/D;R=((s[i+1]-s[i])/(s[r]-s[i]))/D;H=abs((s[i+1]-s[i])*(s[p]-s[i]))/D;if ((R-L)*H<mn){mn=(R-L)*H;ans[0]=s[i]+(s[i+1]-s[i])*(R/D);ans[1]=ans[0]+(s[r]-ans[0])*(H/dis(s[r],ans[0]));ans[2]=ans[1]+(s[i]-ans[0])*((R-L)/dis(s[i],ans[0]));ans[3]=ans[2]+(ans[0]-ans[1]);}}}int main(){scanf("%d",&n);F(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);solve();getans();printf("%.5lf\n",mn);int fir=0;F(i,1,3) if (ans[i]<ans[fir]) fir=i;F(i,0,3) printf("%.5lf %.5lf\n",ans[(i+fir)%4].x,ans[(i+fir)%4].y);return 0;}
0 0
- bzoj1185[HNOI2007]最小矩形覆盖
- bzoj1185【HNOI2007】最小矩形覆盖
- 【HNOI2007】bzoj1185 最小矩形覆盖
- bzoj1185: [HNOI2007]最小矩形覆盖 计算几何 旋转卡壳
- BZOJ1185 [HNOI2007]最小矩形覆盖(旋转卡壳)
- [BZOJ1185][HNOI2007]最小矩形覆盖(凸包+旋转卡壳)
- [BZOJ1185][HNOI2007]最小矩形覆盖(旋转卡壳)
- 1185: [HNOI2007]最小矩形覆盖
- BZOJ 1185: [HNOI2007]最小矩形覆盖
- BZOJ 1185 [HNOI2007]最小矩形覆盖
- 【BZOJ1185】最小矩形覆盖 计算几何 凸包 旋转卡壳
- BZOJ 1185 HNOI2007 最小矩形覆盖 旋转卡壳
- BZOJ 1185 [HNOI2007]最小矩形覆盖 旋转卡壳
- bzoj 1185: [HNOI2007]最小矩形覆盖 旋转卡壳
- bzoj 1185: [HNOI2007]最小矩形覆盖 (旋转卡壳)
- 【BZOJ 1185】[HNOI2007]最小矩形覆盖 旋转卡壳
- bzoj 1185 [HNOI2007]最小矩形覆盖(坑)
- BZOJ 1185([HNOI2007]最小矩形覆盖-旋转卡壳+点集几何意义)
- LinkedHashSet类的使用
- bzoj2300【HAOI2011】防线修建
- 对Run-Time Check Failure #3 - The variable 'a' is being used without being initialized.的处理以及理解
- 隔行扫描
- 1004 of search
- bzoj1185【HNOI2007】最小矩形覆盖
- Visual Studio 性能分析工具 查找 线程死循环
- Binder学习笔记(一)
- 关于创建者模式
- 逐行扫描
- 浅谈JAVA中两种比较方式==和equals
- 第六章:面向对象的程序设计
- JAVA事务——事务特性
- Marsaglia XORshift随机数算法