zoukankan      html  css  js  c++  java
  • 凸包模板

    在此献上凸包模板一份,来自https://blog.csdn.net/yang_deyuan/article/details/78863424

    //凸包模板,以POJ3348为例
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <stack>
    using namespace std;
    typedef pair<int, int> PII;
    typedef long long LL;
    typedef unsigned long long ULL;
    
    const double eps = 1e-8;
    int sgn(double x) {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 1;
    }
    struct Point
    {
        double x,y;
        Point(){}
        Point(double _x,double _y) {
            x = _x;y = _y;
        }
        Point operator -(const Point &b)const {
            return Point(x - b.x,y - b.y);
        }
        //叉积
        double operator ^(const Point &b)const {
            return x*b.y - y*b.x;
        }
        //点积
        double operator *(const Point &b)const {
            return x*b.x + y*b.y;
        }
        void input(){
            scanf("%lf%lf",&x,&y);
        }
    };
    struct Line { 
        Point s,e; 
        Line(){} 
        Line(Point _s,Point _e) {         
            s = _s; e = _e; 
        }
    }; 
    //*两点间距离
    double dist(Point a,Point b)
    {
        return sqrt((a-b)*(a-b));
    }   
    /*
    * 求凸包,Graham算法
    * 点的编号0~n-1
    * 返回凸包结果Stack[0~top-1]为凸包的编号
    */
    const int MAXN = 1010;
    Point List[MAXN];
    int Stack[MAXN];//用来存放凸包的点
    int top;//表示凸包中点的个数
    //相对于List[0]的极角排序
    bool _cmp(Point p1,Point p2) {
        double tmp = (p1-List[0])^(p2-List[0]);
        if(sgn(tmp) > 0)
            return true;
        else if(sgn(tmp) == 0 && sgn(dist(p1,List[0]) - dist(p2,List[0])) <= 0)
            return true;
        else 
            return false;
    }
    void Graham(int n) {
        Point p0;
        int k = 0;
        p0 = List[0];
        //找最下边的一个点
        for(int i = 1;i < n;i++) {
            if( (p0.y > List[i].y) || (p0.y == List[i].y && p0.x > List[i].x) ) {
                p0 = List[i];
                k = i;
            }
        }
        swap(List[k],List[0]);
        sort(List+1,List+n,_cmp);
    	if(n == 1) {
    		top = 1;
    		Stack[0] = 0;
    	}
    	else {
    		Stack[0] = 0;
    		Stack[1] = 1;
    		top = 2;
    		for(int i = 2;i < n;i++) {
    			while(top > 1 && sgn((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]])) <= 0)
    				top--;
    			Stack[top++] = i;
    		}
    	}
    }
    int n;
    int main() {
    	scanf("%d", &n);
    	for(int i = 0; i < n; i++)List[i].input();
    	Graham(n);
    	double res = 0;
    	for(int i = 0; i < top; i++) res += List[Stack[i]] ^ List[Stack[(i + 1) % top]];
    	printf("%d
    ", (int)(res / 100));
    	return 0;
    }
    
  • 相关阅读:
    南阳779
    南阳599
    南阳484
    margin叠加相邻两个元素的上下margin是叠加在一起
    margin
    padding
    css05 字体以及行间距
    mysql相似于oracle的to_char() to_date()方法
    sqlite两表更新update
    SQL查找重复项目
  • 原文地址:https://www.cnblogs.com/TRDD/p/9813499.html
Copyright © 2011-2022 走看看