码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1696 /// 凸包

时间:2018-09-09 11:33:58      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:space   std   分享图片   class   for   技术分享   names   using   operator   

题目大意:

不能向左拐 不能重复走

就是求一个螺旋凸包

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

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

 

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

技术分享图片
#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("\n");
    }

    return 0;
}
View Code

 

POJ 1696 /// 凸包

标签:space   std   分享图片   class   for   技术分享   names   using   operator   

原文地址:https://www.cnblogs.com/zquzjx/p/9612443.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!