zoukankan      html  css  js  c++  java
  • POJ 1696 /// 凸包

    题目大意:

    不能向左拐 不能重复走

    就是求一个螺旋凸包

    把已经是凸包内的点标记一下就行

    因为凸包的性质 所有点都能走到

    注意起点的选择 还有 反复求凸包的过程中边界的改变

    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    #include <cmath>
    using namespace std;
    
    const int N=55;
    const double eps=1e-10;
    double add(double a,double b) {
        if(abs(a+b)<eps*(abs(a)+abs(b))) return 0;
        return a+b;
    }
    struct P {
        double x,y; int id;
        P(){};
        P(double _x,double _y,int _id):x(_x),y(_y),id(_id){}
        P operator -(P p) {
            return P(add(x,-p.x),add(y,-p.y),0); };
        P operator +(P p) {
            return P(add(x,p.x),add(y,p.y),0); };
        P operator *(double d) {
            return P(x*d,y*d,0); };
        double dot(P p) {
            return add(x*p.x,y*p.y); };
        double det(P p) {
            return add(x*p.y,-y*p.x); };
    }p[N], ans[N];
    bool flag[N];
    int  n;
    
    bool cmp(P a,P b) {
        if(a.x==b.x) return a.y<b.y;
        return a.x<b.x;
    }
    void solve(int st) {
        memset(flag,0,sizeof(flag));
        int k=0, t=1;
        while(k<n) {
            for(int i=st;i<n;i++)
                if(flag[p[i].id]==0) {
                    while(k>t && (ans[k-1]-ans[k-2]).det(p[i]-ans[k-1])<=0)
                        k--, flag[ans[k].id]=0;
                    ans[k++]=p[i]; flag[p[i].id]=1;
                }
            t=k;
            for(int i=n-2;i>=0;i--)
                if(flag[p[i].id]==0) {
                    while(k>t && (ans[k-1]-ans[k-2]).det(p[i]-ans[k-1])<=0)
                        k--, flag[ans[k].id]=0;
                    ans[k++]=p[i]; flag[p[i].id]=1;
                }
            t=k; st=0; // 注意边界的修改
        }
    }
    
    int main()
    {
        int t; scanf("%d",&t);
        while(t--) {
            scanf("%d",&n);
            double miny=150.0;
            for(int i=0;i<n;i++) {
                scanf("%d%lf%lf",&p[i].id,&p[i].x,&p[i].y);
                miny=min(miny,p[i].y);
            }
            sort(p,p+n,cmp);
            int t; /// 起点应该取最低的一点 即y最小的一点
            for(int i=0;i<n;i++)
                if(p[i].y==miny) t=i; 
            solve(t);
            printf("%d ",n);
            for(int i=0;i<n;i++)
                printf("%d ",ans[i].id); printf("
    ");
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    VS2010、SQL Server 2008和SQL Server 2012安装详解
    IIS服务寄宿
    C#中错误:不包含适合于入 口点的静态“Main”方法 的解决方法
    硬件的一些性能指标
    SATA SAS SSD 硬盘介绍和评测
    mysql数据库锁定机制
    mysql日志设置优化
    MySQL硬件瓶颈分析
    可扩展性设计之数据切分
    硬件环境对系统性能的影响
  • 原文地址:https://www.cnblogs.com/zquzjx/p/9612443.html
Copyright © 2011-2022 走看看