zoukankan      html  css  js  c++  java
  • poj 1228 凸包

    题目链接:http://poj.org/problem?id=1228

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    const double INF = 1000000000000000.000;
    
    struct Point{
        double x,y;
        Point(double x=0, double y=0) : x(x),y(y){ }    //构造函数
    };
    typedef Point Vector;
    
    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);}
    Vector operator * (double p,Vector A){return Vector(A.x*p,A.y*p);}
    Vector operator / (Vector A , double p){return Vector(A.x/p,A.y/p);}
    
    bool operator < (const Point& a,const Point& b){
        return a.x < b.x ||( a.x == b.x && a.y < b.y);
    }
    
    inline int dcmp(double x){
        if(fabs(x) < eps) return 0;
        else              return x < 0 ? -1 : 1;
    }
    bool operator == (const Point& a, const Point& b){
        return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
    }
    
    ///向量(x,y)的极角用atan2(y,x);
    inline double Dot(Vector A, Vector B){ return A.x*B.x + A.y*B.y; }
    inline double Length(Vector A)    { return sqrt(Dot(A,A)); }
    inline double Angle(Vector A, Vector B)  { return acos(Dot(A,B) / Length(A) / Length(B)); }
    inline double Cross(Vector A, Vector B)  { return A.x*B.y - A.y * B.x; }
    
    
    //凸包:
    /**Andrew算法思路:首先按照先x后y从小到大排序(这个地方没有采用极角逆序排序,所以要进行两次扫描),删除重复的点后得到的序列p1,p2.....,然后把p1和p2放到凸包中。从p3开始,当新的
    点在凸包“前进”方向的左边时继续,否则依次删除最近加入凸包的点,直到新点在左边;**/
    
    //Goal[]数组模拟栈的使用;
    int ConvexHull(Point* P,int n,Point* Goal){
        sort(P,P+n);
        int m = unique(P,P+n) - P;    //对点进行去重;
        int cnt = 0;
        for(int i=0;i<m;i++){       //求下凸包;
            while(cnt>1 && dcmp(Cross(Goal[cnt-1]-Goal[cnt-2],P[i]-Goal[cnt-2])) <= 0)  cnt--;   //如果希望在凸包的边上有输入点,把<= 换成 <.
            Goal[cnt++] = P[i];
        }
        int temp = cnt;
        for(int i=m-2;i>=0;i--){     //逆序求上凸包;
            while(cnt>temp && dcmp(Cross(Goal[cnt-1]-Goal[cnt-2],P[i]-Goal[cnt-2])) <= 0) cnt--;
            Goal[cnt++] = P[i];
        }
        if(cnt > 1) cnt--;  //减一为了去掉首尾重复的;
        return cnt;
    }
    
    bool IsPointOnSegment(Point P,Point A,Point B){
        return dcmp(Cross(A-P,B-P)) == 0 && dcmp(Dot(P-A,P-B)) < 0;
    }
    
    
    /*************************************分 割 线*****************************************/
    
    const int maxn = 1005;
    
    Point P[maxn];
    Point Goal[maxn];
    
    int main()
    {
        freopen("E:\acm\input.txt","r",stdin);
    
        int T;
        cin>>T;
    
        while(T--){
            int n;
            cin>>n;
    
            for(int i=0;i<n;i++){
                scanf("%lf %lf",&P[i].x,&P[i].y);
            }
    
    
            int cnt = ConvexHull(P,n,Goal);
    
            if(cnt <= 2 || cnt*2 > n || n < 6){
                printf("NO
    ");
                continue;
            } cout<<cnt<<"  "<<Goal[cnt].x<<"  "<<Goal[cnt].y<<endl;
            Goal[cnt] = Goal[0];
            int i;
            for(i=0;i<cnt;i++){
                bool flag = false;
                for(int j=0;j<n;j++){
                   // if(j == i || j == i+1) continue;    加了这句就WA 7 次,痛苦啊
                    if(IsPointOnSegment(P[j],Goal[i],Goal[i+1])){
                        flag = true;
                    }
                }
                if(!flag) break;
            }
            if(i<cnt) printf("NO
    ");
            else      printf("YES
    ");
        }
    }
    View Code
  • 相关阅读:
    小谈HTML中的META标签
    如何安装ASPAJAXExtSetup.msi
    <asp:Content> MasterPage技术
    Asp.Net数据控件引用AspNetPager.dll分页
    2011年的最后一天,怎么地也应该写篇博客
    asp.net利用存储过程和div+css实现分页(类似于博客园首页分页)
    Asp.Net 利用TimeSpan类实现时间差计算 并返回所需字符串(类似于SNS)
    最简单的asp.net ajax post,适用于初学者.
    分享AjaxPro或者Ajax实现机制
    Windows 7操作系统 IIS 7 配置asp.net网站伪静态配置问题
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3318203.html
Copyright © 2011-2022 走看看