LA 4728 Squares

原题:
The famous Korean IT company NHN plans to make a digital map of the Earth with help of wireless sensors which spread out in rough terrains. Each sensor sends a geographical data to NHN . But, due to the inaccuracy of the sensing devices equipped in the sensors, NHN only knows a square region in which each geographical data happens. Thus a geographical data can be any point in a square region. You are asked to solve some geometric problem, known as diameter problem, on these undetermined points in the squares. A diameter for a set of points in the plane is defined as the maximum (Euclidean) distance among pairs of the points in the set. The diameter is used as a measurement to estimate the geographical size of the set. NHN wants you to compute the largest diameter of the points chosen from the squares. In other words, given a set of squares in the plane, you have to choose exactly one point from each square so that the diam-
eter for the chosen points is maximized. The sides of the squares are parallel to X-axis or Y -axis, and the squares may have different sizes, intersect each other, and share the same corners. For example, if there are six squares as in the figure on the right, then the largest diameter is defined as the distance between two corner points of squares S 1 and
S 4 .
Given a set of n squares in the plane, write a program to compute the largest diameter D of the points when a point is chosen from each square, and to output D 2 , i.e., the squared value of D.
Input
Your program is to read from standard input. The input consists of T test cases. The number of test
cases T is given in the first line of the input. The first line of each test case contains an integer, n, the
number of squares, where 2 ≤ n ≤ 100,000. Each line of the next n lines contains three integers, x, y,
and w, where (x,y) is the coordinate of the left-lower corner of a square and w is the length of a side
of the square; 0 ≤ x,y ≤ 10,000 and 1 ≤ w ≤ 10,000.
Output
Your program is to write to standard output. Print exactly one line for each test case. The line should
contain the integral value D 2 , where D is the largest diameter of the points when a point is chosen
from each square.
Sample Input
2
3
0 0 1
1 0 2
0 0 1
6
2 1 2
1 4 2
3 2 3
4 4 4
6 5 1
5 1 3
Sample Output
13
85

中文:
给你n个正方形,让你找出所有这些正方形顶点组成的点的最远值的平方是多少?

#include<bits/stdc++.h>
using namespace std;

const double eps=1e-6;

struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};
Point ps[400005],chs[400005];

#define Vector Point

double Sq_dist(Point a,Point b)
{
    return (b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y);
}

bool operator < (const Point &a,const Point &b)//排序用,按照x的坐标从小到大,如果x相同,那么按照y从小到大
{
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
Vector operator +(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}//坐标点相加
Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}//相减

int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else
        return x<0?-1:1;
}

double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}


int ConvexHull(Point *p,int n,Point *ch)//p是所有点,n所有点的个数,ch里面记录形成凸包的点,返回凸包点的个数
{
    sort(p,p+n);
    int m=0;
    for(int i=0;i<n;i++)
    {
        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)
            m--;
        ch[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--)
    {
        while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)
            m--;
        ch[m++]=p[i];
    }
    if(n>1)
        m--;
    return m;
}

double rotating_calipers(Point *ch,int n)
{
    int q=1;
    double ans=0;
    ch[n]=ch[0];
    for(int p=0;p<n;p++)
    {
        while(Cross(Vector(ch[q+1]-ch[p+1]),Vector(ch[p]-ch[p+1]))>Cross(Vector(ch[q]-ch[p+1]),Vector(ch[p]-ch[p+1])))
            q=(q+1)%n;
        ans=max(ans,max(Sq_dist(ch[p],ch[q]),Sq_dist(ch[p+1],ch[q+1])));
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    int n,t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        double x,y,w;
        int ind=0;
        for(int i=0;i<n;i++)
        {
            cin>>x>>y>>w;
            ps[ind].x=x,ps[ind].y=y;
            ind++;
            ps[ind].x=x,ps[ind].y=y+w;
            ind++;
            ps[ind].x=x+w,ps[ind].y=y;
            ind++;
            ps[ind].x=x+w,ps[ind].y=y+w;
            ind++;
        }
        int m=ConvexHull(ps,ind,chs);
        double ans=rotating_calipers(chs,m);
        cout<<(int)ans<<endl;
    }
    return 0;
}






















解答:

裸的旋转卡壳例题,注意输出结果的时候强制转换为int型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值