UVA10256 The Great Divide

怎么又没人写题解,那我来贡献一发好了。

题目意思很简单,平面上有两种颜色的点,问你能否求出一条直线使两种颜色的点完全分开。

首先我们考虑两个点集相离的充要条件,这两个点集的凸包必须相离。(很好证明或者画画图理解一下)

那么怎么判断两个凸包相离,考虑到这里的点的个数不多,我们可以用一种最暴力的方法。

枚举一个凸包上的所有点所有边,然后判断是否与另一个凸包相离即可。

点是否在多边形内?直接暴力转角法即可(不推荐射线法,好理解但不好写,精度不高)

边是否在多边形内,在两个凸包中分别枚举一条边,然后判断是否相交即可。

稍微注意一下精度问题即可,其实计算几何的题主要考验的就是代码的细节能力。

CODE

#include<cstdio>
#include<cmath>
#include<algorithm>
#define RI register int
using namespace std;
typedef double DB;
const int N=505;
const DB EPS=1e-10;
inline int dcmp(DB x)
{
    if (fabs(x)<EPS) return 0; return x<0?-1:1;
}
struct Point
{
    DB x,y;
    Point(DB X=0,DB Y=0) { x=X; y=Y; }
    inline friend bool operator <(Point A,Point B)
    {
        return dcmp(A.x-B.x)<0||(!dcmp(A.y-B.y)&&dcmp(A.y-B.y)<0);
    }
    inline friend bool operator ==(Point A,Point B)
    {
        return !dcmp(A.x-B.x)&&!dcmp(A.y-B.y);
    }
}a[N],b[N],cov_a[N],cov_b[N]; int n,m,cnt_a,cnt_b; DB x,y;
typedef Point Vector;
inline Vector operator -(Point A,Point B) { return Vector(A.x-B.x,A.y-B.y); }
class Computation_Geometry
{
    private:
        inline DB Dot(Vector A,Vector B)
        {
            return A.x*B.x+A.y*B.y;
        }
        inline DB Cross(Vector A,Vector B)
        {
            return A.x*B.y-A.y*B.x;
        }
        inline bool OnSegment(Point p,Point A,Point B)
        {
            return !dcmp(Cross(A-p,B-p))&&dcmp(Dot(A-p,B-p))<0;
        }
        inline bool IsPointInPolygon(Point p,Point *a,int n)
        {
            int t=0; for (RI i=1;i<=n;++i)
            {
                Point p1=a[i],p2=a[(i+1)%n+1];
                if (p1==p||p2==p||OnSegment(p,p1,p2)) return 1;
                int ret=dcmp(Cross(p2-p1,p-p1)),d1=dcmp(p1.y-p.y),d2=dcmp(p2.y-p.y);
                if (ret>0&&d1<=0&&d2>0) ++t; if (ret<0&&d2<=0&&d1>0) --t;
            }
            return t!=0;
        }
        inline bool SegmentProperIntersection(Point A,Point B,Point C,Point D)
        {
            DB c1=Cross(B-A,C-A),c2=Cross(B-A,D-A),c3=Cross(D-C,A-C),c4=Cross(D-C,B-C);
            return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
        }
    public:
        inline int ConvexHull(Point *a,int n,Point *p)
        {
            sort(a+1,a+n+1); n=unique(a+1,a+n+1)-a-1; RI i,top=0;
            for (i=1;i<=n;++i)
            {
                while (top>1&&dcmp(Cross(p[top]-p[top-1],a[i]-p[top]))<=0) --top;
                p[++top]=a[i];
            }
            int t=top; for (i=n-1;i;--i)
            {
                while (top>t&&dcmp(Cross(p[top]-p[top-1],a[i]-p[top]))<=0) --top;
                p[++top]=a[i];
            }
            if (n>1) --top; return top;
        }
        inline bool ConvexPolygonDisjoint(Point *a,int n,Point *b,int m)
        {
            RI i,j; for (i=1;i<=n;++i) if (IsPointInPolygon(a[i],b,m)) return 1;
            for (i=1;i<=m;++i) if (IsPointInPolygon(b[i],a,n)) return 1;
            for (i=1;i<=n;++i) for (j=1;j<=m;++j)
            if (SegmentProperIntersection(a[i],a[i%n+1],b[j],b[j%m+1])) return 1;
            return 0;
        }
}G;
int main()
{
    while (scanf("%d%d",&n,&m),n&&m)
    {
        RI i; for (i=1;i<=n;++i) scanf("%lf%lf",&x,&y),a[i]=Point(x,y);
        for (i=1;i<=m;++i) scanf("%lf%lf",&x,&y),b[i]=Point(x,y);
        cnt_a=G.ConvexHull(a,n,cov_a); cnt_b=G.ConvexHull(b,m,cov_b);
        puts(G.ConvexPolygonDisjoint(cov_a,cnt_a,cov_b,cnt_b)?"No":"Yes");
    };
    return 0;
}

转载于:https://www.cnblogs.com/cjjsb/p/10305920.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
The Cortex-M0 processor does not have a hardware divider, which means that division calculations are performed using software routines. There are various algorithms for performing software division, but one commonly used method is called "long division". In long division, the divisor is repeatedly subtracted from the dividend until the remainder is less than the divisor. The number of times the divisor is subtracted is the quotient, and the remainder is the final result. This process is repeated until all digits of the dividend have been processed. Here is a sample code for performing integer division on Cortex-M0 using long division: ``` int divide(int dividend, int divisor) { int quotient = 0, remainder = 0; int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1; // convert both operands to positive if (dividend < 0) dividend = -dividend; if (divisor < 0) divisor = -divisor; // perform long division for (int i = 31; i >= 0; i--) { remainder <<= 1; // left shift remainder remainder |= (dividend >> i) & 1; // add next bit from dividend to remainder if (remainder >= divisor) { remainder -= divisor; quotient |= (1 << i); // set corresponding bit in quotient } } // apply sign quotient = sign * quotient; return quotient; } ``` Note that this code assumes that both the dividend and divisor are 32-bit integers. It also handles negative operands correctly and applies the correct sign to the result. However, it may not be the most efficient implementation and may need to be optimized for specific use cases.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值