hdu 4946

题意:求解凸包和凸包上两点间共线的点

#include<cmath>
#include<math.h>
#include<cstdio>
#include<iostream>
#include <string.h>
#include <algorithm>
using namespace std;
# define eps 1e-8
#define maxn 5555
struct point
{
    int x,y,v;
    int id;
    point(double x=0,double y=0):x(x),y(y){}
    bool operator==(point const&a)const{
        return x==a.x&&y==a.y;
    }
    bool operator<(point const&a)const{
        return x<a.x||(x==a.x&&y<a.y);
    }
    point operator-(point a){
        return point(x-a.x,y-a.y);
    }
}po[maxn],stack[maxn],p[maxn];
int top,k;
bool cmpx(point a,point b)                             //找最右边的点
{
    if(a.x==b.x)
        return a.y<b.y;
    else
        return a.x<b.x;
}
bool cmp(point a,point b){
    return a.v>b.v;
}
//叉积,结果大于0表示向量p0p1的极角小于p0p2的极角,等于则两向量共线
int  multi(point p1, point p2, point p0)
{
    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

int cmp1(point a,point b)                               //用于排序操作
{
    double k=multi(a,b,po[0]);
    if(fabs(k)<eps)                                       //减少精度误差,计算几何的特点,精度要求高
        return a.x<b.x;
    return k>0;
}
int Cross (point a ,point b){
    return b.y*a.x-a.y*b.x;
}
int dotDet(point a,point b){
    return a.x*b.x+a.y*b.y;
}
bool Gongxian(point  x,point a,point b){
    return (Cross(a-x,b-x)==0)&&dotDet(a-x,b-x)<=0||a==x||b==x;
}
int ConvexHull(point *p,int n,point *ch){
    sort(p,p+n);
    int m=0;
    for(int i=0;i<n;i++){
        
        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--;
        ch[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--){
        while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--;
        ch[m++]=p[i];
    }
    if(n>1)m--;
    return m;
}
int ans[maxn],x[maxn],y[maxn],mp[555][555];
int xcnt,ycnt,same;
double mmi;
int main(){
    int n,_=0;
    while(~scanf("%d",&n)){
        if(n==0)break;
        
        mmi=0,same=0,xcnt=0,ycnt=0;
        memset(ans,0,sizeof ans);
        memset(mp,0,sizeof mp);
        
        
        for(int i=0;i<n;++i){
            scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].v);
            x[xcnt++]=p[i].x,y[ycnt++]=p[i].y;
            p[i].id=i;
            if(i==0){
                mmi=p[i].v;
            }else if(p[i].v>mmi){
                same=0;
                mmi=p[i].v;
            }else if(p[i].v==mmi){
                same++;
            }
        }
        printf("Case #%d: ",++_);
        if(mmi==0){
            for(int i=0;i<n;++i)printf("0");
            printf("\n");
            continue;
        }
        
        sort(p,p+n,cmp);
        sort(x,x+n);
        sort(y,y+n);
        
        xcnt=(int)(unique(x,x+n)-x);
        ycnt=(int)(unique(y,y+n)-y);
        memset(mp,0,sizeof mp);
        
        int all=0;
        for(int i=0;i<=same;++i){
            int xx=(int)(lower_bound(x,x+xcnt,p[i].x)-x);
            int yy=(int)(lower_bound(y,y+ycnt,p[i].y)-y);
            if(p[i].v==mmi){
            if(!mp[xx][yy]){
                po[all].x=p[i].x;
                 po[all].y=p[i].y;
                  po[all++].id=p[i].id;
              }
                mp[xx][yy]++;
            }
            
        }
        
        if(all==1||all==2){
            for(int i=0;i<=same;++i){
                int xx=(int)(lower_bound(x,x+xcnt,p[i].x)-x);
                int yy=(int)(lower_bound(y,y+ycnt,p[i].y)-y);
                if(mp[xx][yy]==1){
                    ans[p[i].id]=1;
                }
            }
                
        }
        
// /*
        
        top=ConvexHull(po,all,stack);
        for(int i=0;i<top;++i){
            int xx=(int)(lower_bound(x,x+xcnt,stack[i].x)-x);
            int yy=(int)(lower_bound(y,y+ycnt,stack[i].y)-y);
            if(mp[xx][yy]==1)ans[stack[i].id]=1;
        }
        for(int i=0;i<top;++i)
            for(int j=0;j<n;++j){
                int xx=(int)(lower_bound(x,x+xcnt,p[j].x)-x);
                int yy=(int)(lower_bound(y,y+ycnt,p[j].y)-y);
                if(p[j].v==mmi&&mp[xx][yy]==1){
                    if(Gongxian(p[j],stack[i],stack[(i+1)%top]))
                        ans[p[j].id]=1;
                }
            }
//*/
/*
        if(all>=3){
            k=-1;
        for(int i=0;i<all;i++){
            if(k==-1||cmpx(po[i],po[k]))
                k=i;
        }
        swap(po[0],po[k]);
        top=2;
        sort(po+1,po+all,cmp1);
        stack[0]=po[0],stack[1]=po[1],stack[2]=po[2];
        for(int i=3;i<all;i++){
            while(top>1&&multi(po[i],stack[top],stack[top-1])>=0)//  = X
                  top--;
              stack[++top]=po[i];
        }
        top++;
    
//      printf("%d\n",top);
 
        for(int i=0;i<top;++i){
            int xx=(int)(lower_bound(x,x+xcnt,stack[i].x)-x);
            int yy=(int)(lower_bound(y,y+ycnt,stack[i].y)-y);
            if(mp[xx][yy]==1)ans[stack[i].id]=1;
        }
        for(int i=0;i<top;++i)
            for(int j=0;j<n;++j){
                int xx=(int)(lower_bound(x,x+xcnt,p[j].x)-x);
                int yy=(int)(lower_bound(y,y+ycnt,p[j].y)-y);
                if(p[j].v==mmi&&mp[xx][yy]==1){
                   if(onSeg(p[j],stack[i],stack[(i+1)%top]))
                      ans[p[j].id]=1;
                   }
                }
        }
 */
        
        for(int i=0;i<n;++i)printf("%d",ans[i]);
        printf("\n");
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值