呵呵哒。WA了无数次,一开始想的办法最终发现都有缺陷。首先需要知道:

1)线段不相交,一定面积为0

2)有一条线段与X轴平行,面积一定为0

3)线段相交,但是能接水的三角形上面线段把下面的线段完全覆盖。

(1),(2)的情况简单,主要是解决(3)。下面对(3)进行讨论,如下图所示,设p1,p2是两线段各自位置较高的点,p0为两线段的交点,向量e是三角形p0p1p2的关于边p1p2的外侧法向量。则当e的终点位于第1,2象限时才会有积水,3,4象限是没有的。判断e的方向可以根据它与(p0p1+p0p2)的点积,e与(p0p1+p0p2)的点积总是大于0的。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const double PI = acos(-1.0);
const int N = ;
const double EPS = 1e-;//实数精度
//点结构类型
struct Point{
double x, y;
Point(double a = , double b = ){ x = a; y = b; }
};
//线段结构类型
struct LineSeg{
Point s, e;
LineSeg(){};
LineSeg(Point a, Point b) : s(a), e(b){}
};
struct Line{
double a, b, c;
};
Point operator-(Point a, Point b){
return Point(a.x - b.x, a.y - b.y);
}
//重载==,判断点a,b是否相等
bool operator==(Point a, Point b){
return abs(a.x - b.x) < EPS&&abs(a.y - b.y) < EPS;
}
//比较实数r1与r2的大小关系
int RlCmp(double r1, double r2 = ){
if (abs(r1 - r2) < EPS)
return ;
return r1>r2 ? : -;
}
//返回向量p1-p0和p2-p0的叉积
double Cross(Point p0, Point p1, Point p2){
Point a = p1 - p0;
Point b = p2 - p0;
return a.x*b.y - b.x*a.y;
}
//判断线段L1与线段L2是否相交(包括交点在线段上)
bool Intersect(LineSeg L1, LineSeg L2){
//排斥实验和跨立实验
return max(L1.s.x, L1.e.x) >= min(L2.s.x, L2.e.x)
&& min(L1.s.x, L1.e.x) <= max(L2.s.x, L2.e.x)
&& max(L1.s.y, L1.e.y) >= min(L2.s.y, L2.e.y)
&& min(L1.s.y, L1.e.y) <= max(L2.s.y, L2.e.y)
&& Cross(L1.s, L1.e, L2.s)*Cross(L1.s, L1.e, L2.e) <=
&& Cross(L2.s, L2.e, L1.s)*Cross(L2.s, L2.e, L1.e) <= ;
}
Line MakeLine(Point a, Point b){
Line L;
L.a = (b.y - a.y);
L.b = (a.x - b.x);
L.c = (b.x*a.y - a.x*b.y);
if (L.a < ){ //保准x系数大于等于0
L.a = -L.a;
L.b = -L.b;
L.c = -L.c;
}
return L;
}
//判直线X,Y是否相交,相交返回true和交点
bool LineIntersect(Line X, Line Y, Point&P){
double d = X.a*Y.b - Y.a*X.b;
if (d == ) //直线平行或者重合
return false;
P.x = (X.b*Y.c - Y.b*X.c) / d;
P.y = (X.c*Y.a - Y.c*X.a) / d;
return true;
}
Point HighPoint(Point a, Point b){
return a.y > b.y ? a : b;
}
Point LowPoint(Point a, Point b){
return a.y < b.y ? a : b;
}
double Dot(Point a, Point b){
return a.x*b.x + a.y*b.y;
}
double Area(LineSeg L1, LineSeg L2){
if (!Intersect(L1, L2))
return ; //不相交
Line X = MakeLine(L1.s, L1.e);
Line Y = MakeLine(L2.s, L2.e);
if (RlCmp(X.a*Y.a) == ) //有一条直线与x平行
return ;
Point inter;
LineIntersect(X, Y, inter); //计算交点
double y = min(max(L1.e.y, L1.s.y), max(L2.e.y, L2.s.y));
double x1 = -(X.b*y + X.c) /X.a;
double x2 = -(Y.b*y + Y.c) / Y.a;
Point p1(x1, y), p2(x2, y);
double area = abs(Cross(inter, p1, p2) / ); //计算面积
if (RlCmp(X.b*Y.b) == ) //有一条线与Y轴平行
return area;
double k1 = -X.a / X.b; //X的斜率
double k2 = -Y.a / Y.b; //Y的斜率
Point high = HighPoint(HighPoint(L1.s, L1.e),HighPoint(L2.s, L2.e));
Point low = LowPoint(HighPoint(L1.s, L1.e), HighPoint(L2.s, L2.e));
if (RlCmp(high.y - low.y) == )
return area;
if (RlCmp(high.x - low.x) == )
return ;
double k = -(high.x - low.x) / (high.y - low.y);
Point mid((high.x + low.x) / , (high.y + low.y) / );
Point op = mid - inter;
Point ans;
if (RlCmp(Dot(op, Point(, k))) >= )
ans = Point(, k);
else
ans = Point(-, -k);
if ((ans.x > && ans.y > || (ans.x< && ans.y>)))
return area;
else
return ;
}
int main(){
int T;
double a, b, c, d;
scanf("%d", &T);
while (T--){
scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
LineSeg L1(Point(a, b), Point(c, d));
scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
LineSeg L2(Point(a, b), Point(c, d));
double area = Area(L1, L2);
printf("%.2lf\n", area);
}
return ;
}

Poj2826 An Easy Problem的更多相关文章

  1. poj2826 An Easy Problem?!【计算几何】

    含[三点坐标计算面积].[判断两线段是否有交点].[求线段交点]模板   An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Tot ...

  2. poj2826 An Easy Problem?!(计算几何)

    传送门 •题意 两根木块组成一个槽,给定两个木块的两个端点 雨水竖直下落,问槽里能装多少雨水, •思路 找不能收集到雨水的情况 我们令线段较高的点为s点,较低的点为e点 ①两条木块没有交点 ②平行或重 ...

  3. UVA-11991 Easy Problem from Rujia Liu?

    Problem E Easy Problem from Rujia Liu? Though Rujia Liu usually sets hard problems for contests (for ...

  4. An easy problem

    An easy problem Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Sub ...

  5. UVa 11991:Easy Problem from Rujia Liu?(STL练习,map+vector)

    Easy Problem from Rujia Liu? Though Rujia Liu usually sets hard problems for contests (for example, ...

  6. POJ 2826 An Easy Problem?!

    An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7837   Accepted: 1145 ...

  7. hdu 5475 An easy problem(暴力 || 线段树区间单点更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=5475 An easy problem Time Limit: 8000/5000 MS (Java/Others ...

  8. 【暑假】[实用数据结构]UVa11991 Easy Problem from Rujia Liu?

    UVa11991 Easy Problem from Rujia Liu?  思路:  构造数组data,使满足data[v][k]为第k个v的下标.因为不是每一个整数都会出现因此用到map,又因为每 ...

  9. HDU 5475 An easy problem 线段树

    An easy problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

随机推荐

  1. IOS开发---菜鸟学习之路--(十二)-利用ASIHTTPRequest进行异步获取数据

    想要实现异步获取的话我这边了解过来有两个非常简单的方式 一个是利用ASIHTTPRequest来实现异步获取数据 另一个则是利用MBProgressHUD来实现异步获取数据 本章就先来讲解如何利用AS ...

  2. 线段树&树状数组模板

    树状数组: #include <bits/stdc++.h> using namespace std; ; struct binit { int a[MAXN], n; void modi ...

  3. Python subprocess.Popen中communicate()和wait()区别

    刚开始我是使用的wait(),但是当adb命令返回太多时,程序就会卡死,查询得知原因后,才使用了communicate(),communicate()返回一个元组:(stdoutdata, stder ...

  4. Xmanager用法(export DISPLAY=客户端IP:0.0)

    1.在用户的目录下找到文件.bash_profile或profile,用vi对其进行编辑.加入下列命令行: DISPLAY=192.168.88.71:0.0;export DISPLAY 2.如果只 ...

  5. LeetCode 62 不同路径

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ).机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角.问总共有多少条不同的路径? 示例 1: 输入: ...

  6. (转载)CentOS 6.5使用aliyun镜像来源

    (原地址:http://www.linuxidc.com/Linux/2014-09/106675.htm) 当我们把CentOS 6.5安装好以后,可以使用这个脚本来使用国内的阿里云镜像源 #!/b ...

  7. 给出 中序&后序 序列 建树;给出 先序&中序 序列 建树

    已知 中序&后序  建立二叉树: SDUT 1489 Description  已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input  输入数据有多组,第一行是一个整数t (t& ...

  8. 频繁模式挖掘中Apriori、FP-Growth和Eclat算法的实现和对比(Python实现)

    最近上数据挖掘的课程,其中学习到了频繁模式挖掘这一章,这章介绍了三种算法,Apriori.FP-Growth和Eclat算法:由于对于不同的数据来说,这三种算法的表现不同,所以我们本次就对这三种算法在 ...

  9. bzoj1086【SCOI2005】王室联邦

    题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1086 sol  :这题水水啊,直接大力DFS就行了 首先当且仅当x<B时无解 对于以x为 ...

  10. hashcode和equals方法

    转自https://www.cnblogs.com/keyi/p/7119825.html 一.equals方法的作用 1.默认情况(没有覆盖equals方法)下equals方法都是调用Object类 ...