德布是一个很大的可乐饮酒者,但他无法帮助它。
为了少喝可乐,他设计了以下装置:
一种长度和高度几乎无限的水箱,底部有无限量的可乐。
在水箱中间有两个木板,木板位于距离水箱边缘无限远的地方,木板和可乐之间的距离是无限的,两个木板可能相交,
Debu将在中午将罐子倒置(稍后完成),可乐将垂直下降。可乐的速度很快,可乐到达底部片刻,所以一些
木板可以保留可乐(因为两块木板可能相交),而德布会喝木板保留的可乐
晚上,Debu将重复这个过程并再次享用可乐。
现在让我们计算一天可以喝多少可乐德布(木板和水箱的宽度为1)
输入
第一行是整数T,表示测试用例的数量(1 <= T <= 1e5)。
每个测试用例有8个整数:x1,y1,x2,y2,x3,y3,x4,y4。
(x1,y1),(x2,y2)是一个挡板的端点,(x3,y3),(x4,y4)是端点的端点。
其他挡板,每个整数不超过10,000。
产量
对于每个测试用例输出一行包含一个实数,精度最多为两位小数 - 可乐的数量。
例子
输入:
1
1 1 2 2 1 1 0 2
输出:
1.00
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define ll long long
using namespace std;
struct node
{
double x,y;
};
int get_line_intersection(double p0_x, double p0_y, double p1_x, double p1_y,
double p2_x, double p2_y, double p3_x, double p3_y, double *i_x, double *i_y)
{
double s02_x, s02_y, s10_x, s10_y, s32_x, s32_y, s_numer, t_numer, denom, t;
s10_x = p1_x - p0_x;
s10_y = p1_y - p0_y;
s32_x = p3_x - p2_x;
s32_y = p3_y - p2_y;
denom = s10_x * s32_y - s32_x * s10_y;
if (denom == 0)
return 0;
bool denomPositive = denom > 0;
s02_x = p0_x - p2_x;
s02_y = p0_y - p2_y;
s_numer = s10_x * s02_y - s10_y * s02_x;
if ((s_numer < 0) == denomPositive)
return 0;
t_numer = s32_x * s02_y - s32_y * s02_x;
if ((t_numer < 0) == denomPositive)
return 0;
if (fabs(s_numer) > fabs(denom) || fabs(t_numer) > fabs(denom))
return 0;
t = t_numer / denom;
if (i_x != NULL)
*i_x = p0_x + (t * s10_x);
if (i_y != NULL)
*i_y = p0_y + (t * s10_y);
return 1;
}
double cross(node a,node b,node c)
{
a.x=a.x-c.x;
a.y=a.y-c.y;
b.x=b.x-c.x;
b.y=b.y-c.y;
return fabs((a.x*b.y-a.y*b.x));
}
node a1,a2,b1,b2;
node r;
int ans;
double res;
void solve1()
{
if((a2.y==b2.y&&b2.y==r.y)||a1.y==a2.y||b1.y==b2.y)
{
return ;
}
if(a2.y>b2.y)
{
swap(a1,b1);
swap(a2,b2);
}
node k;
if(b2.x==b1.x)
{
k.y=a2.y;
k.x=b1.x;
res+=cross(a2,k,r)/2.0;
}
else
{
double ks=(b2.y-b1.y)/(b2.x-b1.x);
ks=(a2.y-b1.y)/ks+b1.x;
k.y=a2.y;
k.x=ks;
res+=cross(a2,k,r)/2.0;
}
}
void solve2()
{
if(ans==0)
{
return ;
}
if((a1.y==b1.y&&b1.y==r.y)||a1.y==a2.y||b1.y==b2.y)
{
return ;
}
if(a1.y<b1.y)
{
swap(a1,b1);
swap(a2,b2);
}
node k;
if(b2.x==b1.x)
{
k.y=a1.y;
k.x=b1.x;
res+=cross(a1,k,r)/2.0;
}
else
{
double ks=(b2.y-b1.y)/(b2.x-b1.x);
ks=b2.x-(b2.y-a1.y)/ks;
k.y=a1.y;
k.x=ks;
res+=cross(a1,k,r)/2.0;
}
}
int Equal(node a,node b)
{
if(a.x==b.x&&a.y==b.y)
return 1;
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
res=0.0;
scanf("%lf%lf%lf%lf",&a1.x,&a1.y,&a2.x,&a2.y);
if(a2.y<a1.y)
swap(a1,a2);
scanf("%lf%lf%lf%lf",&b1.x,&b1.y,&b2.x,&b2.y);
if(b2.y<b1.y)
swap(b1,b2);
if(Equal(a1,b1))
{
r=a1;
}
else if( Equal(a2,b2))
{
r=a2;
}//判断是否端点相交***因为这个wa了一发
else
{
ans=get_line_intersection(a1.x,a1.y,a2.x,a2.y,b1.x,b1.y,b2.x,b2.y,&r.x,&r.y);
if(ans==0)
{
printf("0.00\n");
return 0;
}
}
solve1();
solve2();
printf("%.2lf\n",res);
}
return 0;
}