简单几何(线段相交) 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 ...
随机推荐
- macOSX 访问 win7共享文件
macOSX 访问 win7共享文件 macOSX 访问 win7共享文件 2014年1月8日星期三 开年的第一篇写下自己使用macos中遇到的问题.为后来初学者提供一些浅薄经验. 第一步:WINDO ...
- LR 测试数据库总结
今天工作中需要对mysql进行性能测试 我尝试用LR来做:但是mysql需要现在电脑上安装一个OBDC的mysql驱动器,然后在电脑的管理工具中的数据源中加入这个mysql驱动,测试连接数据库成功,O ...
- js 中数组或者对象的深拷贝和浅拷贝
浅拷贝 : 就是两个js 对象指向同一块内存地址,所以当obj1 ,obj2指向obj3的时候,一旦其中一个改变,其他的便会改变! 深拷贝:就是重新复制一块内存,这样就不会互相影响. 有些时候我们定义 ...
- HDU3345广搜 (P,E,T,#)
War chess is hh's favorite game:In this game, there is an N * M battle map, and every player has his ...
- javascript return false 详解
在大多数情况下,为事件处理函数返回false,可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转到该元素href属性指定的页. Return False 就相当于终止符 ...
- qsort用法总结
一.对int类型数组排序 ]; int cmp ( const void *a , const void *b ) { return *(int *)a - *(int *)b; } qsort(nu ...
- 把sql server 2000的用户表的所有者改成dbo
怎么样把sql server 2000的用户表的所有者,改成dbo,而不是用户名. 推荐使用下面介绍的第二种方法,执行以下查询便可以了.sp_configure 'allow updates','1' ...
- WebSite和WebApplication的区别
1. WebApplication(Web应用程序)和WebSite(网站)的区别:WebSite是为了兼容从ASP转过来的开发人员的习惯而存在的,用起来简单,例如:不需要创建命名控件.C#代码修改以 ...
- html css js
html 回顾 字体:font 属性: color: 颜色 size: 字号 表格:table 标签: tr:表格中的行 td: 单元行中的单元格 th:通常使用在table中的第一行, 成为表头, ...
- Cocos2d 初学基本知识
1. 纹理(Texture) 游戏角色的图像文件在使用前必须解压缩,并转换成 iPhone 和 iPad 的 GPU 可以理解的 格式,同时要加载进 RAM(随机存储器),这样的图像称为纹理.GPU ...