zoukankan      html  css  js  c++  java
  • [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));
    }
    
    
  • 相关阅读:
    bootstrap精简教程
    mvc中EditorFor TextBoxFor什么区别
    jQueryEasyUI DateBox的基本使用
    visual studio 2012如何彻底删除TFS上的团队项目
    清除TFS版本控制信息
    在Vs2012 中使用SQL Server 2012 Express LocalDB打开Sqlserver2012数据库
    display & visibility区别
    SQL localdb 连接字符串
    cpio备份命令
    tar备份工具
  • 原文地址:https://www.cnblogs.com/mollnn/p/12421609.html
Copyright © 2011-2022 走看看