zoukankan      html  css  js  c++  java
  • POJ2826

    雨水竖直下落,给定两条线段,问最多能接多少雨水?

    毒瘤计算几何题目(qwq)

    先考虑一下接不到雨水的情况:

    1.线段不相交

    2.有一条线段水平

    3.平行

    4.小于(90^{。})的夹角不朝上

    怎么判断这些情况?

    第一种:跨立实验

    第二种:直接看纵坐标

    第三种:求斜率

    第四种:过最高点较低的线段的最高点做一条垂直(x)轴的直线,如果与另一条线段相交则接不到雨水

    判断完了之后算一个三角形面积就好了

    注意有可能存在竖直的线段,需要特判

    说起来一套一套的,写来一愣一愣的(qwq)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    namespace red{
    #define y1 qwq
    #define int long long
    #define eps (1e-10)
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	int haku;
    	struct node
    	{
    		double x,y;
    		node (double tx=0,double ty=0){x=tx,y=ty;}
    		inline double operator ^ (const node &t) const//叉积
    		{
    			return x*t.y-y*t.x;
    		}
    		inline node operator - (const node &t) const
    		{
    			return node(x-t.x,y-t.y);
    		}
    	};
    	struct seg
    	{
    		node a,b;
    		double k;
    		inline double slope() const//斜率
    		{
    			return (a.y-b.y)/(a.x-b.x);
    		}
    		inline double turn(node t1,node t2,node t3) const//t1->t2和t1->t3的叉积
    		{
    			return (t2-t1)^(t3-t1);
    		}
    		inline bool across(const seg &t) const//跨立实验
    		{
    			double x=turn(a,b,t.a)*turn(a,b,t.b);
    			if(x>=eps) return 0;
    			x=turn(t.a,t.b,a)*turn(t.a,t.b,b);
    			if(x>=eps) return 0;
    			return 1;
    		}
    		inline node get_node(const seg &t) const//求交点
    		{
    			double b1=a.y-a.x*k,b2=t.a.y-t.a.x*t.k;
    			double x=(b2-b1)/(k-t.k);
    			double y=k*x+b1;
    			return node(x,y);
    		}
    		inline node y_node(double y) const//给y值求点
    		{
    			double bb=a.y-a.x*k;
    			double x=(y-bb)/k;
    			return node(x,y);
    		}
    		inline node x_node(double x) const//给x值求点
    		{
    			double bb=a.y-a.x*k;
    			double y=k*x+bb;
    			return node(x,y);
    		}
    	}d1,d2,d3;
    	inline double are(node a,node b,node c)//三角形面积
    	{
    		return (a.x*b.y+b.x*c.y+c.x*a.y-a.x*c.y-b.x*a.y-c.x*b.y)/2;
    	}
    	inline void solve()
    	{
    		if(d1.a.x!=d1.b.x) swap(d1,d2);
    		if((d1.a.x==d1.b.x&&d2.a.x==d2.b.x)||!d1.across(d2)||d2.b.x==d1.a.x||(d2.a.y==d2.b.y))
    		{
    			puts("0.00");
    			return;
    		}
    		node p=d2.x_node(d1.a.x);
    		double t=min(fabs(d1.b.y-p.y),fabs(d2.b.y-p.y));
    		double h=fabs(d2.y_node(min(d1.b.y,d2.b.y)).x-d1.a.x);
    		printf("%.2lf
    ",h*t/2+eps);
    	}
    	inline void main()
    	{
    		haku=read();
    		while(haku--)
    		{
    			d1.a.x=read(),d1.a.y=read(),d1.b.x=read(),d1.b.y=read();d1.k=d1.slope();
    			if(d1.a.y>d1.b.y) swap(d1.a,d1.b);
    			d2.a.x=read(),d2.a.y=read(),d2.b.x=read(),d2.b.y=read();d2.k=d2.slope();
    			if(d2.a.y>d2.b.y) swap(d2.a,d2.b);
    			if(d1.b.y<d2.b.y) swap(d1,d2);
    			if(d1.a.x==d1.b.x||d2.a.x==d2.b.x)//竖直的线段特判
    			{
    				solve();
    				continue;
    			}
    			if(fabs(d1.k-d2.k)<eps||fabs(d1.k)<eps||fabs(d2.k)<eps||!d1.across(d2))
    			{
    				puts("0.00");
    				continue;
    			}
    			d3.a=d2.b,d3.b=node(d2.b.x,10002);//竖直的直线
    			if(d1.across(d3))
    			{
    				puts("0.00");
    				continue;
    			}
    			node p=d1.get_node(d2),r=d2.b,q=d1.y_node(r.y);
    			printf("%.2lf
    ",fabs(are(p,r,q))+eps);
    		}
    	}
    }
    signed main()
    {
    	red::main();
    	return 0;
    }
    /*
    1
    9235 7382 3788 328 4607 2583 7068 3480 
    
    */
    
  • 相关阅读:
    Java集合概述
    Java8内存结构—永久代(PermGen)和元空间(Metaspace)
    ArrayList分析
    “三次握手,四次挥手”你真的懂吗?
    Object中的方法以及对象相等的判定
    笔记
    Mybatis中的@Param注解
    react与jQuery对比,有空的时候再翻译一下
    队列理论和队列网络模型 queueing theory and queueing network model
    下拉列表autocomplete各种实现方式比较
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12173384.html
Copyright © 2011-2022 走看看