一直在wa,搞来搞去也不知道为啥,先立个flag
6259 2664 8292 9080 1244 2972 9097 9680 答案是6162.65,一直在输出0…
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include<iostream>
#include<cmath>
using namespace std;
const int MAXN = 100000;
const double EPS = 1e-8;
// 带误差比较
inline bool dcmp(double x, double y = 0)
{
return fabs(x - y) <= EPS;
}
/*
* 向量(Vector)或点
*
* 使用原点到一个点 (x, y) 的有向线段表示向量
* 从点 A 到点 B 的向量表示为 A - B
*/
typedef struct Vec
{
double x, y;
Vec(double x = 0, double y = 0) : x(x), y(y) {}
// 相加
Vec operator+(const Vec &v) const
{
return Vec(x + v.x, y + v.y);
}
// 相减
Vec operator-(const Vec &v) const
{
return Vec(x - v.x, y - v.y);
}
// 数乘(伸长、缩短)
Vec operator*(double d) const
{
return Vec(x * d, y * d);
}
Vec operator/(const double d) const
{
return Vec(x / d, y / d);
}
bool operator==(const Vec v)const{
return (v.x==x&&v.y==y);
}
// 范数,用来比较长度,等于长度的平方
double norm() const
{
return x * x + y * y;
}
} Pt;
// 点乘
double dot(const Vec &a, const Vec &b)
{
return a.x * b.x + a.y * b.y;
}
// 叉乘
double cross(const Vec &a, const Vec &b)
{
return a.x * b.y - a.y * b.x;
}
// 线段(Segment),用两个点表示
struct Seg
{
Pt a, b;
Seg(const Pt &a, const Pt &b) : a(a), b(b) {}
// 线段包含点(点在线段上)
bool include(const Pt &p)
{
// PA × PB = 0:PA 与 PB 共线,即点在线段所在的直线上
// PA · PB = 0:PA 与 PB 方向不同(A 和 B 分别在 P 的两边),如果 PA · PB = 0 则 P = A 或 P = B
return dcmp(cross(a - p, b - p)) && dot(a - p, b - p) <= 0;
}
};
// 直线,用两个点表示
struct Line
{
Pt a, b;
Line() {} // 提供一个不需要参数的构造函数
Line(const Pt &a, const Pt &b) : a(a), b(b) {}
bool include(const Pt &p) const
{
return dcmp(cross(a - p, b - p));
}
// 两直线关系(交点个数)
// 0 表示平行(无交点)
// 1 表示相交(一个交点)
// -1 表示重合(无数个交点)
static int relation(const Line &a, const Line &b)
{
if (a.include(b.a) && a.include(b.b)) return -1;
else if (dcmp(cross(a.b - a.a, b.b - b.a))) return 0;
else return 1;
}
// 求两直线交点(需要保证两直线有交点)
static Pt intersect(const Line &a, const Line &b)
{
double s1 = cross(b.a - a.a, b.b - a.a), s2 = cross(b.b - a.b, b.a - a.b);
return a.a + (a.b - a.a) * s1 / (s1 + s2);
}
};
int main()
{
int n,i,j;
cin>>n;
step:while(n--){
Pt p[4];
for(i=0;i<4;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
Seg s1(p[0],p[1]),s2(p[2],p[3]);
Line l1(p[0],p[1]),l2(p[2],p[3]);
if(p[0].y==p[1].y||p[2].y==p[3].y){
cout<<"0.00"<<endl;goto step;
}
int re=l1.relation(l1,l2);
if(re==0||re==-1){
cout<<"0.00"<<endl;goto step;
}
Pt p1=l1.intersect(l1,l2);
if(!s1.include(p1)||!s2.include(p1)){
cout<<"0.00"<<endl;goto step;
}
if(p[0].y<p[1].y)swap(p[0],p[1]);
if(p[2].y<p[3].y)swap(p[2],p[3]);
if(p1==p[0]||p1==p[2]){
cout<<"0.00"<<endl;goto step;
}
if((p[0].x-p[1].x)*(p[0].y-p[1].y)*(p[2].x-p[3].x)*(p[2].y-p[3].y)>0){
if((p[2].x<=p[0].x&&p[2].y<=p[0].y&&cross(p[2]-p[3],p[0]-p[1])>0)||(p[2].x>=p[0].x&&p[2].y>=p[0].y&&cross(p[0]-p[1],p[2]-p[3])>0)){
cout<<"0.00"<<endl;goto step;
}
}
double s;Pt xl1,xl2;
Pt psp;
if(p[0].y<p[2].y){
Line lsp;lsp.a=p[0];lsp.b=p[0];lsp.b.x-=1;
psp=lsp.intersect(lsp,l2);xl1=psp-p1;xl2=p[0]-psp;
printf("%.2f\n",fabs(cross(xl1,xl2))/2);
}
else{
Line lsp;lsp.a=p[2];lsp.b=p[2];lsp.b.x-=1;
psp=lsp.intersect(lsp,l1);xl1=psp-p1;xl2=p[2]-psp;
printf("%.2f\n",fabs(cross(xl1,xl2))/2);
}
}
return 0;
}