An Easy Problem?!

Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17156 Accepted: 2661

Description

It’s raining outside. Farmer Johnson’s bull Ben wants some rain to water his flowers. Ben nails two wooden boards on the wall of his barn. Shown in the pictures below, the two boards on the wall just look like two segments on the plane, as they have the same width.

Your mission is to calculate how much rain these two boards can collect.

Input

The first line contains the number of test cases.
Each test case consists of 8 integers not exceeding 10,000 by absolute value, x1,y1,x2,y2,x3,y3,x4,y4.(x1,y1),(x2,y2)x_1, y_1, x_2, y_2, x_3, y_3, x_4, y_4. (x_1, y_1), (x_2, y_2)x1​,y1​,x2​,y2​,x3​,y3​,x4​,y4​.(x1​,y1​),(x2​,y2​) are the endpoints of one board, and (x3,y3),(x4,y4)(x_3, y_3), (x_4, y_4)(x3​,y3​),(x4​,y4​) are the endpoints of the other one.

Output

For each test case output a single line containing a real number with precision up to two decimal places - the amount of rain collected.

Sample Input

2
0 1 1 0
1 0 2 1
0 1 2 1
1 0 1 2

Sample Output

1.00
0.00

Source

POJ Monthly–2006.04.28, Dagger@PKU_RPWT

题意

  • 给两根固定的线段,问如果从上往下下雨,能最多接住多大面积的雨

题解

  • 线段平行,或者交点不同时在两根线段内,答案为000
  • 首先将每根线段按yyy值排序,先判断两根线段的走势,如果向上走势相反【图1】,那么直接算出答案,如果相同,继续判断接水的位置在左边还是右边【图2,3】,然后找出最上面的那条线段,判断一下是否会完全盖住接口,如果盖住了答案就为000
  • 注意两根线段的最高点相同的情况,特判一下,否则可能会输出nannannan
  • 注意精度问题:由于没有spjspjspj,所以最好的做法是,如果答案大于0,加上epsepseps输出,小于0减去epsepseps输出,当然这题你不这么做不出意外的话会wawawa


代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>using namespace std;
const int maxn=20;
const double eps=1e-6;
#define pi acos(-1.0)int sgn(double k)
{return k<-eps?-1:(k<eps?0:1);
}void print(double a) //数值a保留5位四舍五入输出,
{a+=eps;char buffer[1000];sprintf(buffer+1,"%.2lf",a);  //int len=strlen(buffer+1);bool ok=false;for(int i=1;i<=len;i++) if(!(buffer[i]=='.'||buffer[i]=='0'||buffer[i]=='-')) {ok=true;break;}if(ok) printf("%s",buffer+1);else printf("%.2lf",0.0);    //
}typedef struct point{  //点结构体double x,y;point(double a=0,double b=0) {x=a;y=b;} point operator+(point other) {return point(x+other.x,y+other.y);}point operator-(point other) {return point(x-other.x,y-other.y);}point operator*(double k) {return point(x*k,y*k);}friend bool operator==(const point &a,const point &b) {return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}double dot(point other) { //点乘,即数量积,内积(ABcos<A,B>)return x*other.x+y*other.y;}double cha(point other) { //叉乘,即向量积,外积(ABsin<A,B>)return x*other.y-y*other.x;}bool onseg(point p1,point p2) {//判断q是否在线段p1-p2上point q=*this;return sgn((p1-q).cha(p2-q))==0&&sgn((p1-q).dot(p2-q))<=0;}friend bool cross(point p1,point p2,point q1,point q2) { //判断线段p1-p2与线段q1-q2有交点,不包括平行和重合if(parallel(p1,p2,q1,q2)) return false;point inter=intersect(p1,p2,q1,q2);if(inter.onseg(p1,p2)&&inter.onseg(q1,q2)) return true;return false;}friend double dis(point p1,point p2) {     //计算两点距离return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}friend point intersect(point p1,point p2,point q1,point q2) {//计算直线p1-p2是否与直线q1-q2的交点return p1+(p2-p1)*((q2-q1).cha(q1-p1)/(q2-q1).cha(p2-p1));}friend bool parallel(point p1,point p2,point q1,point q2) { //判断线段p1-p2是否与线段q1-q2平行,重合也会返回truereturn sgn((q2-q1).cha(p2-p1))==0;}friend double dis_point_line(point a,point b,point c) { //点a到直线[b,c]的距离double cos0=(a-b).dot(c-b)/(dis(point(0,0),a-b)*dis(point(0,0),c-b));if(sgn(cos0-1)>=0) return 0;return dis(point(0,0),a-b)*sin(acos(cos0));}void print() {printf("x:%.3lf  y:%.3lf\n",x,y);}
}Vector;point p[4];void solve(point p1,point p2,point p3)
{if(sgn((point(p2.x+1,p2.y)-p2).cha(p3-p1))==0) {print(0);printf("\n");return;}point cros=intersect(p1,p3,p2,point(p2.x+1,p2.y));double h=dis_point_line(p1,cros,p2);double area=dis(point(0,0),cros-p2)*h/2.0;print(area);printf("\n");
}int main()
{int t;scanf("%d",&t);while(t--) {for(int i=0;i<4;i++) scanf("%lf %lf",&p[i].x,&p[i].y);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(parallel(p[0],p[1],p[2],p[3])) {print(0.0);printf("\n");continue;}if(!cross(p[0],p[1],p[2],p[3])) {print(0.0);printf("\n");continue;}if(p[1]==p[3]||p[0]==p[1]||p[2]==p[3]) {print(0.0);printf("\n");continue;}point inter=intersect(p[0],p[1],p[2],p[3]);if(sgn((p[0].x-p[1].x)*(p[2].x-p[3].x))>=0) {if(sgn(p[1].x-p[0].x)>=0) {        if(sgn((p[1]-inter).cha(p[3]-inter))>0) {swap(p[0],p[2]);swap(p[1],p[3]);}if(sgn(p[1].x-p[3].x)>=0) {print(0);printf("\n");continue;}if(sgn(p[3].y-p[1].y)<=0) solve(inter,p[3],p[1]);else solve(inter,p[1],p[3]);}else {if(sgn((p[1]-inter).cha(p[3]-inter))<0) {swap(p[0],p[2]);swap(p[1],p[3]);}if(sgn(p[1].x-p[3].x)<=0) {print(0);printf("\n");continue;}if(sgn(p[3].y-p[1].y)<=0) solve(inter,p[3],p[1]);else solve(inter,p[1],p[3]);}}else{if(sgn(p[3].y-p[1].y)<=0) solve(inter,p[3],p[1]);else solve(inter,p[1],p[3]);}}
}

「POJ2826」An Easy Problem?!【计算几何】相关推荐

  1. POJ - 2826 An Easy Problem?!(计算几何,好题)

    题目链接:点击查看 题目大意:给出两条线段,问组成的容器最多能接多少雨水 题目分析:既然是接雨水,那么肯定只能是漏斗状,很容易排除掉两种情况: 其中有一条线段平行于x轴 两条线段不相交 还有一种比较难 ...

  2. POJ 2826 An Easy Problem?! 叉积求多边形面积 【计算几何】

    ACM博客_kuangbin POJ 2826 An Easy Problem?! An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536 ...

  3. 数论六之计算几何——An Easy Problem,Ancient Berland Circus,Open-air shopping malls

    可检验模板正确度 An Easy Problem?! Ancient Berland Circus Open-air shopping malls An Easy Problem?! problem ...

  4. 空中悬停、翻滚转身、成功着陆,我用强化学习「回收」了SpaceX的火箭

    视学算法报道 编辑:杜伟.陈萍 我自己造了个「火箭」,还把它回收了. SpaceX 作为一家太空探索技术公司是美国一家民营航天制造商和太空运输公司,由伊隆 · 马斯克于 2002 年创办,目标是降低太 ...

  5. opengl实现3d点云_3D视觉CV界的终极体现形式,计算机如何「看」这个三维世界

    机器之心原创 作者:陈萍 打开手机进行人脸解锁:VR.AR 技术带来如此虚拟却真实的场景--3D 视觉几乎无所不能,在智能家居.智能安防.汽车电子.工业测量.新零售.智能物流等领域发挥重要作用,堪称赋 ...

  6. 《预训练周刊》第5期:智源等研究力证:GPT语言理解能力不输BERT、盘点NLP预训练「兵器谱」...

    No.05 智源社区 预训练组 预 训 练 研究 观点 资源 活动 关于周刊 超大规模预训练模型是当前人工智能领域研究的热点,为了帮助研究与工程人员了解这一领域的进展和资讯,智源社区整理了第5期< ...

  7. AI突破的「阴暗面」:怎样防止GPT-3跟人类学坏?

    原文:IEEE Spectrum 编译:梦佳 近期,大规模语言模型频频出现在公众视野中. 前有Google发布首个万亿级模型 Switch Transformer,参数量达到1.6万亿,速度是Goog ...

  8. 「机器学习」机器学习算法优缺点对比(汇总篇)

    作者 | 杜博亚 来源 | 阿泽的学习笔记 「本文的目的,是务实.简洁地盘点一番当前机器学习算法」.文中内容结合了个人在查阅资料过程中收集到的前人总结,同时添加了部分自身总结,在这里,依据实际使用中的 ...

  9. LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

    #2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小 ...

  10. 开源的恶果,程序员正在「自掘坟墓」

    大家好,我是校长. 最近开源社区里发生了一件大事,在 IT 圈引起了轰动,那就是:faker.js 开源项目的作者删除了该项目的所有代码. 01 事情是这样的 作为一个著名的 nodejs 工具库,F ...

最新文章

  1. c#如何取自身应用程序文件名和路径?
  2. C++ 调试技术:addr2line
  3. 也说科研的兴趣与自信
  4. [洛谷3812]【模板】线性基
  5. Linux常用测试命令
  6. 手机端网站底部悬浮 广告代码 代关闭_网站被劫持,网站被劫持了应该怎么办?怎么解决网站被劫持?...
  7. jzoj3339-[NOI2013模拟]wyl8899和法法塔的游戏【博弈论,暴力】
  8. 《Python Cookbook 3rd》笔记(2.17):在字符串中处理html和xml
  9. 用git上传自己的第一个github项目
  10. 念整数 mooc翁恺
  11. 初用WEB IOU,IE LAB备战启航
  12. 以后给孩子起名字不用发愁了,先存着
  13. LTE 注网流程log分析
  14. 【拓展】一个故事讲完CPU的工作原理
  15. 3DMax如何安装?3DMax2018软件安装图文教程全解
  16. python修改系统环境变量_Python实战—修改环境变量
  17. IPv4向IPv6转换的几种技术分析
  18. 如何写一份高可读性的软件工程设计文档
  19. java tea collection_Javaの集合学习
  20. 36艺教育完成3000万元Pre-A轮融资,星火资本投资

热门文章

  1. 如何用Vegas制作故障特效
  2. 工厂设备状态监控可视化解决方案
  3. 应用数据难互通 如何打破小微企业“信息壁垒”?
  4. 计算机系统动态库修复,无法定位程序输入点于动态链接库修复解决方法 | 专业网吧维护...
  5. Javascript和C#正则只保留英文、数字、汉语、空格
  6. dev-c++文件名取名问题(踩坑)
  7. sublime中文乱码
  8. 以太网口差分电平_以太网差分信号线在两层PCB板上的布线方法
  9. 单片机攻略3——C51入门
  10. 【学习方法】常见算法在实际项目中的应用