[HAOI2014] 穿越封锁线

给定一个多边形,求一条竖直向上的射线与多边形相交的距离。(n leq 50)

Solution

求出与所有边的交点(包括端点),按 (y) 坐标升序排序

如果一个交点不是端点,我们就改变当前状态

如果一个交点是端点,则当这个点两侧的线段分居在射线左右两侧时才改变当前状态。注意这里的两侧是不严格的,也就是说如果其中一段与射线重合,那么就直接算作分居两侧。

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

#define int long long
const int N = 105;
const double eps = 1e-6;

struct point {
    double x,y;
    bool operator < (const point &b) {
        return y < b.y;
    }
    bool operator == (const point &b) {
        return fabs(x-b.x)<eps && fabs(y-b.y)<eps;
    }
    void read() {
        cin>>x>>y;
    }
} p[N],q,oo;

double xmult(point p1,point p2,point p0){
	return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

int same_side(point p1,point p2,point l1,point l2){
	return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;
}

int dots_inline(point p1,point p2,point p3){
	return fabs(xmult(p1,p2,p3))<eps;
}

int dot_online_in(point p,point l1,point l2){
	return fabs(xmult(p,l1,l2))<eps&&(l1.x-p.x)*(l2.x-p.x)<eps
            &&(l1.y-p.y)*(l2.y-p.y)<eps;
}

int intersect_in(point u1,point u2,point v1,point v2){
	if (!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))
		return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);
	return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
}

point intersection(point u1,point u2,point v1,point v2){
	point ret=u1;
	double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
			/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
	ret.x+=(u2.x-u1.x)*t;
	ret.y+=(u2.y-u1.y)*t;
	return ret;
}

int n;
point s[N];
int top;

signed main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) {
        p[i].read();
    }
    q.read();
    p[n+1]=p[1];
    p[0]=p[n];
    oo.x=q.x;
    oo.y=1e9;
    for(int i=1;i<=n;i++) {
        if(p[i].x==q.x && p[i+1].x==q.x) continue;
        if(intersect_in(q,oo,p[i],p[i+1])) {
            s[++top]=intersection(q,oo,p[i],p[i+1]);
        }
    }
    sort(s+1,s+top+1);
    double ans=0;
    int flag=0;
    for(int i=1;i<=top;i++) {
        if(flag) ans+=s[i].y-s[i-1].y;
        bool isp = 0;
        for(int j=1;j<=n;j++) if(p[j]==s[i]) isp=j;
        if(isp==0) {
            flag^=1;
        }
        else {
            if((fabs(p[isp+1].x-q.x)<eps) ||
               (fabs(p[isp-1].x-q.x)<eps)) {

               }
            else if((p[isp+1].x-q.x)*(p[isp-1].x-q.x)<-eps) {
                flag^=1;
            }
        }
    }
    cout<<(int)(floor(ans));
}

原文地址:https://www.cnblogs.com/mollnn/p/12421609.html