UVALive 4728 Squares (平面最远点对)

题意:n个平行于坐标轴的正方形,求出最远点对的平方

题解:首先求出凸包,可以证明最远点对一定是凸包上的点对,接着可以证明最远点对(每个点的对踵点)一定只有3*n/2对

接着使用旋转卡壳找到最远点对,但是白书上的算法过于麻烦

所以我看到一个简单想法就是:

可以直接枚举每个点,接着枚举这个点对应最远的点(三角形面积最大)

这儿对踵点满足一个单峰性质,所以可以使用类似双指针方式维护

//n个平行于坐标轴的正方形,求出最远点对的平方
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define eps 1e-8
#define sgn(x) (x<-eps? -1 : x<eps? 0:1)
#define zero(x) (((x)>0?(x) : -(x))<eps)
const int Max=5e5+7;
struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
    inline Point operator-(const Point& a)const
    {
        return Point(x-a.x,y-a.y);
    }
    inline bool operator<(const Point& a)const
    {
        return sgn(x-a.x)<0||zero(x-a.x)&&sgn(y-a.y)<0;
    }
    inline bool operator!=(const Point& a)const
    {
        return !(zero(x-a.x)&&zero(y-a.y));
    }
};
typedef Point Vector;
double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}
double Dis(Point A,Point B)
{
    return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
int ConvexHull(Point* p,int n,Point* convex)
{
    sort(p,p+n);
    int m=0,k=1;
    for(int i=0; i<n; ++i)
    {
        if(p[k-1]!=p[i])
        {
            p[k++]=p[i];
        }
    }
    n=k;
    for(int i=0; i<n; ++i)
    {
        while(m>1&&Cross(convex[m-1]-convex[m-2],p[i]-convex[m-2])<0)
            m--;
        convex[m++]=p[i];
    }
    k=m;
    for(int i=n-2; i>=0; --i)
    {
        while(m>k&&Cross(convex[m-1]-convex[m-2],p[i]-convex[m-2])<0)
            m--;
        convex[m++]=p[i];
    }
    if(n>1)
        m--;
    return m;
}
double RotateStuck(Point* convex,int n)//旋转卡壳(前提:一个凸包),注意凸包去重点不要三点共线
{
    double ans=0;
    int q=1;
    convex[n]=convex[0];//避免取模
    for(int p=0; p<n; ++p)//枚举一条边
    {
        while(Cross(convex[p+1]-convex[p],convex[q+1]-convex[p])>//这儿用的是三角形面积的比较
              Cross(convex[p+1]-convex[p],convex[q]-convex[p]))//找到对应p这条个点的最远点(由于单峰函数,所以结果类似双指针)
            q=(q+1)%n;
        ans=max(ans,max(Dis(convex[p],convex[q]),Dis(convex[p+1],convex[q+1])));
    }
    return ans;
}
Point poi[Max],convex[Max];
double Solve(int n)//求出最远点对的平方
{
    double fpp=0;
    int m=ConvexHull(poi,n,convex);//先找凸包
    fpp=RotateStuck(convex,m);//旋转卡壳求对踵点(可以求出凸包上的最远点对)
    return fpp*fpp;
}
int main()
{
    int t,n;
    double w,x,y;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; ++i)
        {
            scanf("%lf%lf%lf",&x,&y,&w);
            poi[4*i]=Point(x,y);
            poi[4*i+1]=Point(x+w,y);
            poi[4*i+2]=Point(x,y+w);
            poi[4*i+3]=Point(x+w,y+w);
        }
        printf("%.0f\n",Solve(4*n));
    }
    return 0;
}
时间: 2024-10-12 17:04:36

UVALive 4728 Squares (平面最远点对)的相关文章

uvalive 4728 Squares

题意:求所有正方形中两点距离最大值的平方值. 思路:旋转卡壳法. 分别用数组和vector存凸包时,旋转卡壳代码有所不同. 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 #include<memory.h> 7 #include<cstdlib> 8 #include

poj2187 求平面最远点对,garham_scan算法求凸包

poj2187 求平面最远点对,garham_scan算法求凸包 Beauty Contest Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 29666   Accepted: 9180 Description Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'M

UVA 4728 Squares(凸包+旋转卡壳)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17267 [思路] 凸包+旋转卡壳 求出凸包,用旋转卡壳算出凸包的直径即可. [代码] 1 #include<cstdio> 2 #include<vector> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 struct Pt { 8

SVM与LR的比较

两种方法都是常见的分类算法,从目标函数来看,区别在于逻辑回归采用的是logistical loss,svm采用的是hinge loss.这两个损失函数的目的都是增加对分类影响较大的数据点的权重,减少与分类关系较小的数据点的权重.SVM的处理方法是只考虑support vectors,也就是和分类最相关的少数点,去学习分类器.而逻辑回归通过非线性映射,大大减小了离分类平面较远的点的权重,相对提升了与分类最相关的数据点的权重.两者的根本目的都是一样的.此外,根据需要,两个方法都可以增加不同的正则化项

OpenGL投影矩阵

概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它将所有定点数据从观察坐标转换到裁减坐标.接着,这些裁减坐标通过除以w分量的方式转换到归一化设备坐标(NDC). 因此,我们需要记住一点:裁减变换(视锥剔除)与NDC变换都保存在GL_PROJECTION矩阵中.下述章节描述如何从6个限定参数(左.右.下.上.近平面.远平面)构建投影矩阵. 注意,视锥剔除(裁减)在裁减坐标

三维图像技术与OpenGL基础理论

英文原文:3D Graphics with OpenGL Basic Theory 中文译文:三维图像技术与OpenGL基础理论 1. 计算机图像硬件 1.1 GPU(图像处理单元) 如今,计算机拥有用来专门做图像处理显示的GPU模块,拥有独立的图像处理储存(显存). 1.2 像素和画面 任何图像显示都是基于栅格的格式.一个栅格既是一张二维的像素直角坐标网.像素具有两个属性:颜色和位置.颜色通常使用RGB(红绿蓝)来表示,典型的有用8位或者24位二进制位(真彩色)表示一种颜色.位置则用坐标(x,

css3--transition

一,转换定义: 1,能够改变元素的形状,尺寸,位置 2,转换分两种: 2D转换:只能在X,Y轴发生改变: 例子:旋转(rotate).拉伸(scale).平移(move).倾斜(skew) 3D转换:除了X,Y轴以外还能Z轴变化. 如:空间旋转... 二,转换属性(transform:使用2D,3D): 1,提示: 目前浏览器并不是完全支持所有的Transform ,IE9.Firefox 和Opera 仅支持2D transforms ,相应的CSS定义为:-ms-transform .-mo

css(高级)之“”转换“”笔记

一.定义:转换是使元素改变形状.尺寸和位置的一种效果.又称为变形. 分为;2D和3D转换.2D转换只能在X.Y轴发生改变;如:平移(move).倾斜(skew).旋转(rotate).缩放(scale). 3D转换可以实现空间转换. 二.属性: 1.transform属性:应用2D或3D转换; 取值:none(默认值不进行任何转换).fransform-function(表示一个或多个转换函数:平移旋转,倾斜.缩放) 写法:(1)transform:rotate(30deg)角度为正值时顺时针旋

学习shader之前必须知道的东西之计算机图形学(一)渲染管线

引言 shader到底是干什么用的?shader的工作原理是什么? 其实当我们对这个问题还很懵懂的时候,就已经开始急不可耐的要四处搜寻有关shader的资料,恨不得立刻上手写一个出来.但看了一些资料甚至看了不少cg的语法之后,我们还是很迷茫,UNITY_MATRIX_MVP到底是个什么矩阵?它和v.vertex相乘出来的又是什么玩意?当这些问题困扰我们很久之后,我们才发现,原来我们是站在浮沙上筑高台,根基都没有打牢当然不可能盖得起高楼大厦了. 那根基是什么呢?大牛曰,计算机图形学. shader