• 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
    ", diameter2(po));
    	}
    	return 0;
    }
    
  • 相关阅读:
    iOS 将对象的属性和属性值拆分成key、value,通过字符串key来获取该属性的值
    [IOI2005] Riv 河流
    [洛谷P4549] [模板] 裴蜀定理
    [NOIp2013] 货车运输
    [NOIp2015] 运输计划
    18.10.01模拟赛总结
    [洛谷P3369] 普通平衡树 Treap & Splay
    [NOIp2016] 组合数问题
    [洛谷P4777] [模板] 扩展中国剩余定理
    [洛谷P3384] [模板] 树链剖分
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6783304.html
Copyright © 2020-2023  润新知