[POJ2826]An Easy Problem?!(计算几何)
来源:互联网 发布:网络情缘一线牵表情包 编辑:程序博客网 时间:2024/05/27 01:26
=== ===
这里放传送门
=== ===
题解
这题特判的情况比较多。。首先应该判断这两个线段是不是有且仅有一个焦点。不相交或者重合的情况都是应该出0的。然后就是分情况讨论了,可以发现如果这两个线段的斜率一个大于0一个小于0,它们一定是能接到雨水的,否则要判断从上面竖直落下来的雨水能否打到下面的线段上。一开始用的方法是从上面那条线段的一个端点引了一条竖直向下的直线看有没有交点,但是如果这两个东西的端点是恰好对齐的,实际上也是接不到雨水的但是它会在端点处有一个交点。实际上直接判横坐标大小关系就可以了。
最后就是对于能接到雨水的情况算能接到多少,就是从两条线段的上端点引平行于x轴的直线看是否与另一条相交,求出交点以后算三角形面积就可以了。
这个题精度非常恶心,有可能出现-0.00这样的东西,输出的时候要加个eps。然后就是如果G++不行的话拿C++交。。。
代码
#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const double eps=1e-8;const double inf=1e7;int T;struct Vector{ double x,y; Vector(double X=0,double Y=0){x=X;y=Y;} Vector operator + (const Vector &a){return Vector(x+a.x,y+a.y);} Vector operator - (const Vector &a){return Vector(x-a.x,y-a.y);} double operator * (const Vector &a){return x*a.y-y*a.x;} Vector mul(double t){return Vector(x*t,y*t);} void read(){scanf("%lf%lf",&x,&y);} };struct Line{ Vector P,v,p[2]; double k; Line(){P=Vector();v=Vector();p[0]=p[1]=Vector();} void get(){ p[0].read();p[1].read(); if (p[1].y-p[0].y>eps) swap(p[0],p[1]); P=p[0];v=p[1]-p[0]; if (fabs(v.x)<eps) k=inf; else k=v.y/v.x; }//P存储靠上的那个端点 void rev(){ p[0].x=-p[0].x;p[1].x=-p[1].x; P=p[0];v=p[1]-p[0]; if (fabs(v.x)<eps) k=inf; else k=v.y/v.x; }}l1,l2;bool Ins(Line l1,Line l2){ Vector a1,a2,b1,b2,t1,t2; if (fabs(l1.v*l2.v)<eps) return false;//特判平行的情况 a1=l1.P;a2=a1+l1.v;b1=l2.P;b2=b1+l2.v; if (min(a1.x,a2.x)>max(b1.x,b2.x)||min(b1.x,b2.x)>max(a1.x,a2.x)) return false; if (min(a1.y,a2.y)>max(b1.y,b2.y)||min(b1.y,b2.y)>max(a1.y,a2.y)) return false; t1=a1-b1;t2=a2-b1; if ((t1*l2.v)*(t2*l2.v)>eps) return false; t1=b1-a1;t2=b2-a1; if ((t1*l1.v)*(t2*l1.v)>eps) return false; return true;}Vector GLI(Line a,Line b){ Vector u=a.P-b.P; double t=(b.v*u)/(a.v*b.v); return a.P+a.v.mul(t);}bool check(){return l2.P.x-l1.P.x>eps;}double Calc(){ Line tmp; Vector i1,i2; tmp.P=l1.P;tmp.v=Vector(inf,0);//引出平行于x轴的直线 if (Ins(tmp,l2)){ i1=GLI(tmp,l2);i2=GLI(l1,l2); return fabs((l1.P-i1)*(i2-i1)/2); } tmp.P=l2.P;tmp.v=Vector(-inf,0); if (Ins(tmp,l1)){ i1=GLI(tmp,l1);i2=GLI(l1,l2); return fabs((l2.P-i1)*(i2-i1)/2); } return 0;}int main(){ scanf("%d",&T); for (int wer=1;wer<=T;wer++){ l1.get();l2.get(); if (!Ins(l1,l2)){printf("0.00\n");continue;} if (l1.k*l2.k<-eps){ if (l1.k>l2.k) swap(l1,l2); printf("%.2lf\n",Calc()); continue; } if (l1.k<-eps){l1.rev();l2.rev();} if (l1.k<l2.k) swap(l1,l2); if (!check()) printf("0.00\n"); else printf("%.2lf\n",Calc()); } return 0;}
偏偏在最后出现的补充说明
在此郑重感谢cloverhxy和zyf2000用无数的WA挖出了这道题的所有坑点(手动滑稽
阅读全文
0 0
- [POJ2826]An Easy Problem?!(计算几何)
- [POJ2826]An Easy Problem?!(计算几何)
- [POJ2826] An Easy Problem?! && 计算几何
- poj2826 An Easy Problem?!
- POJ2826-An Easy Problem?!
- poj2826 An Easy Problem?!
- poj2826—An Easy Problem?
- poj 2826 An Easy Problem?!(计算几何)
- poj-2826 An Easy Problem?!(计算几何,好题)
- HDU 5572 An Easy Physics Problem (计算几何+模板)
- HDU 5572-An Easy Physics Problem (计算几何)
- POJ 2826 An Easy Problem?!(计算几何)
- POJ 2826 An Easy Problem?!(计算几何)
- POJ 2826 An Easy Problem 计算几何
- HDU5572 An Easy Physics Problem 【计算几何】
- POJ 2826 An Easy Problem?! <计算几何>
- An Easy Problem?! POJ 2826 计算几何
- An Easy Problem?!(poj2826线段相交,直线线段相交)
- 机器学习算法应用场景实例六十则
- 分析安卓ANR tombstone使用ndk-stack addr2line
- 聚类算法应用场景实例十则
- Android debuggerd 源码分析
- 关联规则应用场景实例十则
- [POJ2826]An Easy Problem?!(计算几何)
- jdk1.7和jdk1.8区别
- Combination Sum II问题及解法
- Linux 软件看门狗 watchdog 喂狗
- 2017.6.15 数字表格 思考记录
- jdk1.5、1.6、1.7新特性详细介绍(整理)
- [BZOJ2741][FOTILE模拟]L(分块+可持久化Trie)
- 使用TensorFlow基于阿里云AI实现图像识别技术(HR)
- Java PHP 开发常用软件以及前端开发ps dw软件Office2007百度网盘打包下载