hihocoder 1582 : Territorial Dispute(凸包)

传送门

题意

分析

求一个凸包即可
1.所有点在凸包上且点数>3,令凸包上第1,3点为'A',其余点为'B'
2.部分点在凸包上,令凸包上点为'A',其余点为'B'
3.无可行情况

附代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

const LL eps=1e-10;
const LL pi=acos(-1.0);

int dcmp(LL x)
{
    if(x==0LL) return 0;
    else return x<0? -1:1;
}

struct Point
{
    LL x,y;
    int id;
    void read()
    {
        scanf("%lld%lld",&x,&y);
    }
    void output()
    {
        printf("%lld %lld\n",x,y);
    }
    Point(LL x_=0,LL y_=0)
    {
        x=x_,y=y_;
    }
    Point operator -(const Point& rhs)
    {
        return Point(x-rhs.x,y-rhs.y);
    }
    Point operator +(const Point& rhs)
    {
        return Point(x+rhs.x,y+rhs.y);
    }
    Point operator *(const LL& t)
    {
        return Point(x*t,y*t);
    }
    Point operator /(const LL& t)
    {
        return Point(x/t,y/t);
    }
    bool operator ==(const Point& rhs)
    {
        return dcmp(x-rhs.x)==0&&dcmp(y-rhs.y)==0;
    }
    bool operator<(const Point& rhs)const
    {
        return x<rhs.x||x==rhs.x&&y<rhs.y;
    }
};
typedef Point Vector;

LL Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}

LL Dot(Vector A,Vector B)
{
    return A.x*B.x+A.y*B.y;
}

LL Area2(Point A,Point B,Point C)
{
    return Cross(B-A,C-A);
}

bool SegmentProperIntersection(Point A1,Point B1,Point A2,Point B2)
{
    LL c1=Cross(B1-A1,A2-A1),c2=Cross(B1-A1,B2-A1),
           c3=Cross(B2-A2,A1-A2),c4=Cross(B2-A2,B1-A2);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}

bool OnSegment1(Point P,Point A,Point B)
{
    return dcmp(Cross(P-A,P-B))==0 && dcmp(Dot(P-A,P-B))<=0;
}

bool SegmentIntersection(Point A1,Point B1,Point A2,Point B2)
{
    return SegmentProperIntersection(A1,B1,A2,B2) ||
            OnSegment1(A2,A1,B1)||OnSegment1(B2,A1,B1) ||
            OnSegment1(A1,A2,B2)||OnSegment1(B1,A2,B2);
}

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&&dcmp(Area2(ch[m-2],ch[m-1],p[i]))<=0) --m;    //直到 ch[m-2],ch[m-1],p[i] 不是顺时针且不在同一直线
        ch[m++]=p[i];
    }
    int k=m;
    for (int i=n-2; i>=0; --i)
    {
        while(m>k&&dcmp(Area2(ch[m-2],ch[m-1],p[i]))<=0) --m;
        ch[m++]=p[i];
    }
    return n>1?m-1:m;
}

//==============================================

int n,nc;
Point p[105],ch[105];
int c[105];

bool judge()
{
    int cnt=ConvexHull(p,n,ch);//计算在凸包上的点
    if(cnt<n)
    {
        for(int i=0;i<cnt;++i) c[ch[i].id]=1;
        return 1;
    }
    else if(cnt>3)
    {
        c[ch[0].id]=c[ch[2].id]=1;
        return 1;
    }
    else return 0;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        memset(c,0,n*sizeof(int));
        for(int i=0;i<n;i++)
            p[i].read(),p[i].id=i;
        if(judge())
        {
            puts("YES");
            for(int i=0;i<n;++i) if(c[i]) putchar('A');else putchar('B');
            puts("");
        }
        else
            puts("NO");
    }
    return 0;
}

posted @ 2017-09-24 10:32  遗风忘语  阅读(127)  评论(0编辑  收藏  举报