UVAL 4728 Squares(旋转卡壳)

Squares

【题目链接】Squares

【题目类型】旋转卡壳

&题解:

听着算法名字,感觉挺难,仔细一看之后,发现其实很简单,就是依靠所构成三角行面积来快速的找对踵点,就可以省去很多的复杂度了.旋转的复杂度是O(n),之后还有计算每条边对应的对踵点复杂度平均大约O(n/2)在实际中也许可以更快

&代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

struct Point {
    int x,y;
    Point(int x=0,int y=0): x(x),y(y) {}
};
typedef Point Vector;
Vector operator - (const Vector& A,const Vector& B) {return Vector(A.x-B.x , A.y-B.y);}
bool operator == (const Point& a,const Point& b) {return a.x==b.x&&a.y==b.y;}
bool operator < (const Point& a,const Point& b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
int Cross(Vector A,Vector B) {return A.x*B.y - A.y*B.x;}
int Dist2(const Point& a,const Point& b) {return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}

vector<Point> ConvexHull(vector<Point> p) {
    sort(p.begin(),p.end());
    p.erase(unique(p.begin(),p.end()) , p.end());
    int n=p.size(), m=0;
    vector<Point> ch(n+1);
    for(int i=0; i<n; i++) {
        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-1])<=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-1])<=0) m--;
        ch[m++]=p[i];
    }
    if(m>1) m--;
    ch.resize(m);
    return ch;
}

int diameter2(vector<Point>& points) {
    vector<Point> p=ConvexHull(points);
    int n=p.size();
    if(n==1) return 0;
    if(n==2) return Dist2(p[0] , p[1]);
    p.push_back(p[0]);
    int ans=0;
    for(int u=0, v=1; u<n; u++) {
        for(;;) {
            int diff = Cross(p[u+1]-p[u] , p[v+1]-p[v]);
            if( diff<=0 ) {
                ans=max(ans , Dist2(p[u],p[v]));
                //2个三角形面积相等
                if(diff==0) ans=max(ans, Dist2(p[u], p[v+1]));
                break;
            }
            v=(v+1)%n;
        }
    }
    return ans;
}

int main() {
    freopen("E:1.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d" ,&n);
        vector<Point> po;
        for(int i=0; i<n; i++) {
            int x,y,w;
            scanf("%d%d%d",&x,&y,&w);
            po.push_back(Point(x,y));
            po.push_back(Point(x+w,y));
            po.push_back(Point(x,y+w));
            po.push_back(Point(x+w,y+w));
        }
        printf("%d\n", diameter2(po));
    }
    return 0;
}

转载于:https://www.cnblogs.com/s1124yy/p/6783304.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值