• UVA10173 Smallest Bounding Rectangle


    最小矩形覆盖,旋转卡壳
    https://www.luogu.com.cn/problem/UVA10173

    先求出凸包,那么一个结论就是最终这个矩形必然有一边必然和凸包的某一边重合
    于是我们就旋转卡壳枚举这个边,再另外维护三个指针,分别表示距离这个边最远的点,以目前这个线段的方向为正方向,最靠前、靠后的点,或者说是旋转整个凸包使得目前的线段平行于 (x) 轴时,横坐标最大、最小的点
    第一个指针好维护,只要叉积算面积即可,另外两个需要用点积判他和他后一个点组成的线段是否与当前线段同向/反向
    于是此时的矩形就要一边和这个线段重合、另外三边卡在这三个点上
    那么只要实现点到线段距离即可求出矩形长、宽,从而得到面积

    一个细节是维护上面那个“最靠后”的指针时,初始值要赋为离第一条线段最远的点

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define reg register
    #define EN puts("")
    #define INT_INF ((int)0x3f3f3f3f)
    #define LL_INF ((long long)0x3f3f3f3f3f3f3f3f)
    inline int read(){
    	register int x=0;register int y=1;
    	register char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=getchar();}
    	return y?x:-x;
    }
    #define N 1006
    #define PI 3.1415926575898
    struct Vector{
    	double x,y,ang;
    	inline int operator < (const Vector &b)const{return ang==b.ang?(x==b.x?y<b.y:x<b.x):ang>b.ang;}
    	inline double len(){return std::sqrt(x*x+y*y);}
    	inline Vector operator - (const Vector &b)const{return (Vector){x-b.x,y-b.y,0};}
    	inline Vector operator + (const Vector &b)const{return (Vector){x+b.x,y+b.y,0};};
    	inline Vector operator * (const double &b)const{return (Vector){x*b,y*b,0};}
    	inline double operator ^ (const Vector b)const{return x*b.y-y*b.x;}
    	inline double operator * (const Vector &b)const{return x*b.x+y*b.y;}
    };
    inline double dis(Vector a,Vector b,Vector c){return std::abs(((c-a)^(c-b))/(a-b).len());}
    inline int graham(int n,Vector *p,Vector *stack){
    	for(reg int i=2;i<=n;i++)if(p[i]<p[1]) std::swap(p[i],p[1]);
    	for(reg int i=2;i<=n;i++) p[i].ang=atan2(p[i].y-p[1].y,p[i].x-p[1].x);
    	std::sort(p+2,p+1+n);
    	stack[1]=p[1];int top=1;
    	for(reg int i=2;i<=n;i++){
    		while(top>1&&((p[i]-stack[top])^(stack[top]-stack[top-1]))<=0) top--;
    		stack[++top]=p[i];
    	}
    	stack[++top]=p[1];
    	return top;
    }
    int n;
    Vector p[N],q[N];
    inline int nex(reg int i){return i==n?2:(i+1);}
    int main(){
    while(n=read()){
    	for(reg int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y),p[i].ang=0;
    	if(n<=2){puts("0.0000");continue;}
    	n=graham(n,p,q);
    	if(n<=3){puts("0.0000");continue;}
    	double ans=1e18;
    	Vector o;
    	reg int j=3,h=1,g;
    	while(std::abs((q[j]-q[1])^(q[j]-q[2]))<=std::abs((q[nex(j)]-q[1])^(q[nex(j)]-q[2]))) j=nex(j);
    	g=j;
    	for(reg int i=1;i<n;i++){
    		while(std::abs((q[j]-q[i])^(q[j]-q[i+1]))<=std::abs((q[nex(j)]-q[i])^(q[nex(j)]-q[i+1]))) j=nex(j);
    		while((q[nex(h)]-q[h])*(q[i+1]-q[i])>=0) h=nex(h);
    		while((q[nex(g)]-q[g])*(q[i]-q[i+1])>=0) g=nex(g);
    		Vector o=(Vector){q[i].y-q[i+1].y,q[i+1].x-q[i].x};
    		ans=std::min(ans,dis(q[i],q[i+1],q[j])*dis(q[h],q[h]+o,q[g]));
    	}
    	printf("%.4lf
    ",ans);
    }
    	return 0;
    }
    
  • 相关阅读:
    每次运行caffe代码之前需要考虑修改的地方
    caffe solver 配置详解
    python获取当前文件路径以及父文件路径
    Python 文件夹及文件操作
    安装NVIDIA驱动时禁用自带nouveau驱动
    博客园转载其他博客园的文章:图片和源码
    分布式开放消息系统(RocketMQ)的原理与实践
    RocketMQ基本概念及原理介绍
    rocketmq 4.3.2 解决远程不能消费问题,解决未识别到公网IP问题
    osx免驱网卡推荐
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/14931133.html
Copyright © 2020-2023  润新知