POJ 2826 An Easy Problem?!(线段相交,比较角度大小)

题意:给你两根线段,问能装多少雨水。

这题要比较线与水平面的角度的大小。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;
const double INF = 1e20;
const double EPS = 1e-6;
bool zero(double t)
{
    return -EPS<t&&t<EPS;
}
struct cvector{
    double x,y;
    cvector(double a,double b){x=a,y=b;}
    cvector(){}
};
cvector operator+(cvector a,cvector b){
    return cvector(a.x+b.x,a.y+b.y);
}
cvector operator-(cvector a,cvector b){
    return cvector(a.x-b.x,a.y-b.y);
}
cvector operator*(double a,cvector b){
    return cvector(a*b.x,a*b.y);
}
double operator*(cvector a,cvector b){
    return a.x*b.x+a.y*b.y;
}
double operator^(cvector a,cvector b){
    return a.x*b.y-b.x*a.y;
}
double length(double t){return t>=0?t:-t;}
double length(cvector t){return sqrt(t*t);}
struct cpoint{
    double x,y;
    cpoint(double a,double b){x=a,y=b;}
    cpoint(){}
};
cvector operator-(cpoint a,cpoint b){
    return cvector(a.x-b.x,a.y-b.y);
}
double dist(cpoint a,cpoint b){
    return length(a-b);
}
struct cline{
    cpoint a,b;
};
bool intersect(cline a,cline b){
    if(zero((a.a-a.b)^(b.a-b.b))) return false;
    return ((a.a-b.a)^(b.b-b.a))*((a.b-b.a)^(b.b-b.a))<EPS
    &&((b.a-a.a)^(a.b-a.a))*((b.b-a.a)^(a.b-a.a))<EPS;
}
cpoint inter(cline a,cline b)
{
    double x,y;
    y=((b.a.x-a.a.x)*(a.b.y-a.a.y)*(b.b.y-b.a.y)+(a.b.x-a.a.x)*(b.b.y-b.a.y)*a.a.y-(a.b.y-a.a.y)*(b.b.x-b.a.x)*b.a.y)/((a.b-a.a)^(b.b-b.a));
    x=((b.a.y-a.a.y)*(a.b.x-a.a.x)*(b.b.x-b.a.x)+(a.b.y-a.a.y)*(b.b.x-b.a.x)*a.a.x-(a.b.x-a.a.x)*(b.b.y-b.a.y)*b.a.x)/((b.b-b.a)^(a.b-a.a));
    return cpoint(x,y);
}
bool over(cvector a,cvector b)
{
    if(a.x*b.x<EPS) return false;
    if((1/length(a)*(a.y))>(1/length(b)*(b.y))&&fabs(a.x)>=fabs(b.x)) return true;
    if((1/length(a)*(a.y))<(1/length(b)*(b.y))&&fabs(b.x)>=fabs(a.x)) return true;
    return false;
}
int main()
{
    freopen("in.txt","r",stdin);
    int cas;
    cline l1,l2;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%lf%lf%lf%lf",&l1.a.x,&l1.a.y,&l1.b.x,&l1.b.y);
        scanf("%lf%lf%lf%lf",&l2.a.x,&l2.a.y,&l2.b.x,&l2.b.y);
        if(!intersect(l1,l2))
        {
            printf("0.00\n");continue;
        }
        cpoint x = inter(l1,l2);
      //  cout<<x.x<<" - "<<x.y<<endl;
        cvector a,b;
        if(l1.a.y>x.y) a=(l1.a-x);
        else a=(l1.b-x);
        if(l2.a.y>x.y) b=(l2.a-x);
        else b=(l2.b-x);
        if(a.y<=0||b.y<=0||over(a,b))
        {
            printf("0.00\n");continue;
        }
        if(a.y>b.y)
        {
            a = (b.y/a.y)*(a);
        }
        else
        {
            b= (a.y/b.y)*(b);
        }
        printf("%.2lf\n",fabs(length(a^b)/2)+EPS);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值