zoukankan      html  css  js  c++  java
  • hihoCoder #1582 Territorial Dispute 几何凸包

    hihoCoder #1582  Territorial Dispute

    题意:给出 n 个点,染两种颜色,问是否有一种染色方案,使得没有任何一条直线可以划分开这两种颜色的点。

    tags:求个凸包,如果内部有点就内部点染一种颜色,如果内部没点就凸包上的点交替染。 还有 n==3 且在一条直线上的情况,特判一下。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const double eps=1e-8;
    const int N = 200005;
    
    struct Point { double x, y; int id; } p[N], sta[N];
    int isZero(double x) {      //x是否为0
        return (x>0 ? x : -x) < eps;
    }
    double crossProd(Point A,Point B,Point C) {     //叉积,这样写即A->B到A->C逆时针为正
        return (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);
    }
    double Dis(Point A,Point B) {
        return sqrt((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));
    }
    //以最左下的点为基准点,其他各点(逆时针方向)以极角从小到大的排序规则
    bool cmp(Point a, Point b)
    {
        double tmp = crossProd(p[1], a, b);    //极角大小转化为求叉乘
        if(tmp>0 || (isZero(tmp)&&Dis(p[1],a)<Dis(p[1],b))) return 1;
        else return 0;
    }
    int top;
    void Graham(int _n)
    {
        int mi=1;
        double mx=p[1].x, my=p[1].y;
        for(int i=2; i<=_n; ++i)    //找到最左下点
            if(my>p[i].y || my==p[i].y&&mx>p[i].x)
                mi=i, my=p[i].y, mx=p[i].x;
        swap(p[1], p[mi]);  //最左下点要换到p开头,不能让它和它自己比
        sort(p+2, p+1+_n, cmp);
        sta[1]=p[1], sta[2]=p[2], sta[3]=p[3];
        p[_n+1]=p[1];    //在结尾加最左下点为结束点
        top=2;
        for(int i=3; i<=_n+1; i++) {
            //加入一个点后,向右偏拐或共线,则上一个点不在凸包内,则--top,该过程直到不向右偏拐或没有三点共线的点
            while(crossProd(sta[top-1],sta[top],p[i])<0 && top) top--;
            sta[++top]=p[i];
        }
    }
    
    int n;
    bool ans[N];
    int main()
    {
        int T;  scanf("%d", &T);
        while(T--)
        {
            mes(ans, false);
            scanf("%d", &n);
            rep(i,1,n)
                scanf("%lf%lf", &p[i].x, &p[i].y),  p[i].id=i;
            if(n<3) { puts("NO");  continue; }
            if(n==3 && (p[1].y-p[2].y)*(p[2].x-p[3].x) != (p[2].y-p[3].y)*(p[1].x-p[2].x) ) {
                puts("NO");  continue;
            }
            puts("YES");
            Graham(n);
            --top;
            if(top<n)
            {
                rep(i,1,top) ans[sta[i].id]=true;
            }
            else
            {
                rep(i,1,top) if(i&1) ans[sta[i].id]=true;
            }
            rep(i,1,n)
                printf("%c", ans[i] ? 'A' : 'B');
            puts("");
        }
    
        return 0;
    }
  • 相关阅读:
    phpize使用方法
    PHP安装redis扩展
    lnmp 搭建后,nginx下php文件404但是html文件正常访问
    nginx配置https访问安装ssl证书
    Linux安装git最新版本
    微信公众号开发处理微信昵称带图片问题
    如何撰写技术文档
    Asp.Net Core 2.0实现HttpResponse中繁切换
    EF6.0 下sql语句自动生成的参数类型decimal(18,2)修改
    Windows注册表详解
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7606476.html
Copyright © 2011-2022 走看看