简单几何(线段相交) POJ 2826 An Easy Problem?!
题意:两条线段看成两块木板,雨水从上方往下垂直落下,问能接受到的水的体积
分析:恶心的分类讨论题,考虑各种情况,尤其是入口被堵住的情况,我的方法是先判断最高的两个点是否在交点的同一侧,然后看看是否高的点覆盖了低的点,用叉积判断方向,其他的情况见网上的解释。貌似没有什么卡精度的数据。最后膜拜楼教主,难以望其项背。。。
/************************************************
* Author :Running_Time
* Created Time :2015/10/30 星期五 18:36:27
* File Name :POJ_2826.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
const double PI = acos (-1.0);
int dcmp(double x) {
if (fabs (x) < EPS) return 0;
else return x < 0 ? -1 : 1;
}
struct Point {
double x, y;
Point () {}
Point (double x, double y) : x (x), y (y) {}
Point operator + (const Point &r) const {
return Point (x + r.x, y + r.y);
}
Point operator - (const Point &r) const {
return Point (x - r.x, y - r.y);
}
Point operator * (double p) const {
return Point (x * p, y * p);
}
Point operator / (double p) const {
return Point (x / p, y / p);
}
bool operator < (const Point &r) const {
return x < r.x || (!dcmp (x - r.x) && y < r.y);
}
bool operator == (const Point &r) const {
return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
}
};
typedef Point Vector;
Point read_point(void) {
double x, y;
scanf ("%lf%lf", &x, &y);
return Point (x, y);
}
double dot(Vector A, Vector B) {
return A.x * B.x + A.y * B.y;
}
double cross(Vector A, Vector B) {
return A.x * B.y - A.y * B.x;
}
Point line_line_inter(Point p, Vector V, Point q, Vector W) {
Vector U = p - q;
double t = cross (W, U) / cross (V, W);
return p + V * t;
}
bool can_inter(Point a1, Point a2, Point b1, Point b2) {
double c1 = cross (a2 - a1, b1 - a1), c2 = cross (a2 - a1, b2 - a1),
c3 = cross (b2 - b1, a1 - b1), c4 = cross (b2 - b1, a2 - b1);
return dcmp (c1) * dcmp (c2) <= 0 && dcmp (c3 * c4) <= 0;
}
double area_triangle(Point a, Point b, Point c) {
return fabs (cross (b - a, c - a)) / 2.0;
} int main(void) {
int T; scanf ("%d", &T);
Point a1, a2, b1, b2;
while (T--) {
a1 = read_point ();
a2 = read_point ();
b1 = read_point ();
b2 = read_point (); //a1,b1是纵坐标较高的点
if (dcmp (a1.y - a2.y) < 0 || (dcmp (a1.y - a2.y) == 0 && dcmp (a1.x - a2.x) > 0)) swap (a1, a2);
if (dcmp (b1.y - b2.y) < 0 || (dcmp (b1.y - b2.y) == 0 && dcmp (b1.x - b2.x) > 0)) swap (b1, b2);
if (dcmp (a1.x - a2.x) == 0 && dcmp (b1.x - b2.x) == 0) { //竖直平行
puts ("0.00"); continue;
}
if (dcmp (a1.y - a2.y) == 0 || dcmp (b1.y - b2.y) == 0) { //水平平行
puts ("0.00"); continue;
}
if (dcmp (cross (a1 - a2, b1 - b2)) == 0) { //共线
puts ("0.00"); continue;
}
if (!can_inter (a1, a2, b1, b2)) { //不能相交
puts ("0.00"); continue;
}
Point p = line_line_inter (a1, a2 - a1, b1, b2 - b1), q;
if (dcmp (a1.y - p.y) <= 0 || dcmp (b1.y - p.y) <= 0) { //有一个点纵坐标低于交点
puts ("0.00"); continue;
}
double ans = 0.0;
if (dcmp (a1.y - b1.y) == 0) {
ans = area_triangle (a1, b1, p);
}
else if (dcmp (a1.y - b1.y) < 0) {
if (dcmp (a1.x - p.x) > 0 && dcmp (b1.x - p.x) > 0) {
if (dcmp (b1.x - a1.x) >= 0 && cross (a1 - p, b1 - p) >= 0) { //入口被覆盖,以下同
puts ("0.00"); continue;
}
}
else if (dcmp (a1.x - p.x) < 0 && dcmp (b1.x - p.x) < 0) {
if (dcmp (b1.x - a1.x) <= 0 && cross (b1 - p, a1 - p) >= 0) {
puts ("0.00"); continue;
}
}
q = line_line_inter (a1, Vector (1, 0), b1, b2 - b1);
ans = area_triangle (a1, q, p);
}
else {
if (dcmp (a1.x - p.x) > 0 && dcmp (b1.x - p.x) > 0) {
if (dcmp (a1.x - b1.x) >= 0 && cross (b1 - p, a1 - p) >= 0) {
puts ("0.00"); continue;
}
}
else if (dcmp (a1.x - p.x) < 0 && dcmp (b1.x - p.x) < 0) {
if (dcmp (a1.x - b1.x) <= 0 && cross (a1 - p, b1 - p) >= 0) {
puts ("0.00"); continue;
}
}
q = line_line_inter (a1, a2 - a1, b1, Vector (1, 0));
ans = area_triangle (b1, q, p);
}
double eps = 1e-8;
printf ("%.2f\n", ans + eps);
} //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n"; return 0;
}
简单几何(线段相交) POJ 2826 An Easy Problem?!的更多相关文章
- 简单几何(线段相交) POJ 2653 Pick-up sticks
题目传送门 题意:就是小时候玩的一种游戏,问有多少线段盖在最上面 分析:简单线段相交,队列维护当前最上的线段 /******************************************** ...
- 简单几何(线段相交) POJ 1410 Intersection
题目传送门 题意:一个矩形和一条线段,问是否有相交 分析:考虑各种情况.坑点:给出的矩形的两个端点是无序的,还有线段完全在矩形内也算相交 /****************************** ...
- 简单几何(线段相交) POJ 1066 Treasure Hunt
题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...
- POJ 2826 An Easy Problem? 判断线段相交
POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...
- 简单几何(线段相交)+模拟 POJ 3449 Geometric Shapes
题目传送门 题意:给了若干个图形,问每个图形与哪些图形相交 分析:题目说白了就是处理出每个图形的线段,然后判断是否相交.但是读入输出巨恶心,就是个模拟题加上线段相交的判断,我第一次WA不知道输出要按字 ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
- POJ 2826 An Easy Problem?![线段]
An Easy Problem?! Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12970 Accepted: 199 ...
- POJ 2826 An Easy Problem?!
An Easy Problem?! Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7837 Accepted: 1145 ...
- POJ 2826 An Easy Problem?!(线段交点+简单计算)
Description It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Be ...
随机推荐
- 淘宝(阿里百川)手机客户端开发日记第二篇 android首页之顶部轮播特效制作 (二)
1.我们来设计flash_slide.xml 布局,这个xml主要做成模块化,方便其它的activity可以动态去调用. flash_slide.xml内容如下: <?xml version=& ...
- FATAL: ActionView::Template::Error (application.css isn't precompiled):
iwangzheng.com tty:[0] jobs:[0] cwd:[/opt/logs/m]13:02 [root@a02.cmsapi$ tail thin\ server\ \(0.0.0. ...
- 用Matplotlib绘制二维图像
唠叨几句: 近期在做数据分析,需要对数据做可视化处理,也就是画图,一般是用Matlib来做,但Matlib安装文件太大,不太想直接用它,据说其代码运行效率也很低,在网上看到可以先用Java做数据处理, ...
- linux shell 字符串操作详解 (长度,读取,替换,截取,连接,对比,删除,位置 )
在做shell批处理程序时候,经常会涉及到字符串相关操作.有很多命令语句,如:awk,sed都可以做字符串各种操作. 其实shell内置一系列操作符号,可以达到类似效果,大家知道,使用内部操作符会省略 ...
- 如何选择Html.RenderPartial和Html.RenderAction
Html.RenderPartial与Html.RenderAction这两个方法都是用来在界面上嵌入用户控件的. Html.RenderPartial是直接将用户控件嵌入到界面上: <%Htm ...
- 《C#高级编程》学习笔记------C#中的事件和委托
本文转载自张子阳 目录 委托的作用 将方法绑定到委托 事件的来由 Observer设计模式 .Net Framework中的委托与事件 引言 委托 和 事件在 .Net Framework中的应用 ...
- 在Xcode5和Android Studio添加工程间的依赖
正在编辑中,尚未完成 先看看ios的target是什么,请先参看http://www.cocoachina.com/bbs/read.php?tid-10884.html做个大概了解 这里有一篇文章, ...
- php 字符串负值判断
2014年9月9日 11:54:54 $a = '-1'; $b = (int)$a; $c = is_numeric($a); if ($a) { echo 1; //echo 1 } else { ...
- Java用Scanner类获取用户输入
用Java编写程序时,有些数据需要用户输入,这个时候需要调用java提供的Scanner类,这个类在包java.util下,比如求一个矩形的面积,简单的看一下用法: import java.util. ...
- Linux系统排查3——I/O篇
当磁盘无法写入的时候,一般有以下可能: 文件系统只读 磁盘已满 I节点使用完 一. 遇到只读的文件系统 文件系统自动设置成只读可能是系统自我保护的一种机制,因此需要实现弄清究竟是什么原因造成了文件系统 ...