• 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
  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/zquzjx/p/9612443.html
Copyright © 2020-2023  润新知