poj 2826 Easy Problem
来源:互联网 发布:后缀io域名 编辑:程序博客网 时间:2024/05/17 22:07
看着题标我就知道肯定要被坑,诶学长推荐的十道几何入门题。。怎么越来越坑了,题目我都没看明白,后面才知道原来求两线段构成个V来接水,但情况好像有点多啊,好多接不到水啊的,还要求交点啊,都不会啊,弱菜只能看着别人的代码,学习怎么去解题,代码好长的感觉,有的甚至上两百行了,要不要这么残暴啊,选了好几份看了思路又学习别人的各种模版巧了代码还是一直WA····,各种坐标x和y弄混,+写成-太是考验了,诶最后硬是撑了一天半整整才算明白。
思路:
1.求两线段构成的槽能装多少雨水,其实就是求相交后那个凹槽面积,不过这里有很多情况。(注:雨水垂直落地的)
情况:1.不相交就肯定不能接水了, 2.相交的话有会有在一条直线上重合的情况这种也不行 3.相交交点刚好为线段端点也不行 4相交后上线段完全遮挡了下线段也不行
这些都是接不到水的情况
剩下的就是可以接水的了,首先求出交点,然后以两线段中那个向上的Y坐标最小的作为一个端点,在用横线相交求出另外一个交点,最后根据x乘求面积。
这个题细心的地方有很多,而且也包含很多几何常用知识,很好的一个题,收获很大。
#include<stdio.h>#include<stdlib.h>#include<math.h>const double eps=1e-8;struct point{ double x; double y;}s,d1,d2;;//s交点,d1,d2为由s为端点的剩余三角形的两个点 struct line{ point a; point b;}line1,line2;int dblcmp(double x){//由于精度问题,这里是一个比较模版 if(fabs(x)<eps) return 0; return x>0.0?1:-1; }double xmult(point p0,point p1,point p2){ //叉乘 return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);} double dotmult(point p0,point p1,point p2){//点乘,可以很好的判断一个在直线上的点,是否已然在这个直线上的一个线段上 return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y); }int judgecross(line L1,line L2){ double s1,s2,s3,s4; s1=dblcmp(xmult(L1.a,L1.b,L2.a)); s2=dblcmp(xmult(L1.a,L1.b,L2.b)); s3=dblcmp(xmult(L2.a,L2.b,L1.a)); s4=dblcmp(xmult(L2.a,L2.b,L1.b)); if(s1*s2<0&&s3*s4<0)return 1;//常规相交 if(s1==0&&dblcmp(dotmult(L2.a,L1.a,L1.b))<=0)return 1;//非常规相交 这种情况就需要用点成来判断是否只是在直线上而非线段上 if(s2==0&&dblcmp(dotmult(L2.b,L1.a,L1.b))<=0)return 1; if(s3==0&&dblcmp(dotmult(L1.a,L2.a,L2.b))<=0)return 1; if(s4==0&&dblcmp(dotmult(L1.b,L2.a,L2.b))<=0)return 1; return 0;}void getcross(line L1,line L2){//获得交点 s=L1.a; double t=((L1.a.x-L2.a.x)*(L2.a.y-L2.b.y)-(L1.a.y-L2.a.y)*(L2.a.x-L2.b.x))//这是利用了面积比与线段比的关系由于底相同,就便是边的比 /((L1.a.x-L1.b.x)*(L2.a.y-L2.b.y)-(L1.a.y-L1.b.y)*(L2.a.x-L2.b.x)); s.x+=(L1.b.x-L1.a.x)*fabs(t);//fabs可以去掉,但我不知道为什么可以,这里有向面积符号没有影响么? s.y+=(L1.b.y-L1.a.y)*fabs(t);}void getpoint(point p1, point p2, double yy){ double dx=p2.x-p1.x; double dy=p2.y-p1.y; d1.y=yy; if(dblcmp(dx)==0) d1.x=p1.x; else{ double k=dy/dx; d1.x=(yy-p1.y)/k+p1.x; } } double solve(line L1,line L2){ line L3;//作为一个替代板,和L2的b点相交并且平行于y轴; if(dblcmp((L1.b.x-L1.a.x)*(L2.b.y-L2.a.y)-(L2.b.x-L2.a.x)*(L1.b.y-L1.a.y))==0)return 0.00;//两条线段重合了 L3.a.x=L3.b.x=L2.b.x; L3.a.y=L2.b.y; L3.b.y=L2.b.y+10000.0; if(judgecross(L1,L3))return 0.00;//被上板覆盖接不到雨水 getcross(L1,L2);//获得交点 if(!dblcmp(s.y-L1.b.y)||!dblcmp(s.y-L2.b.y))return 0.00;//交点刚好是线段端点 getpoint(L1.a,L1.b,L2.b.y);//获得实际高边的三角形端点 d2=L2.b;//因为这是比较矮的那条边已经是三角形的一个顶点 return fabs(xmult(s,d1,d2))/2.0; }void swp(point &p1,point &p2){ point p; p.x=p1.x, p.y=p1.y; p1.x=p2.x, p1.y=p2.y; p2.x=p.x, p2.y=p.y;}int main(){ int t; double ans; scanf("%d",&t); while(t--){ scanf("%lf %lf %lf %lf",&line1.a.x,&line1.a.y,&line1.b.x,&line1.b.y); scanf("%lf %lf %lf %lf",&line2.a.x,&line2.a.y,&line2.b.x,&line2.b.y); if(dblcmp(line1.a.y-line1.b.y)>0)//先把这些点处理一下方便用,这里将每条线段的两个点按照纵坐标从小到大排好 swp(line1.a,line1.b); if(dblcmp(line2.a.y-line2.b.y)>0) swp(line2.a,line2.b); if(dblcmp(line1.b.y-line2.b.y)<0){//这里同样是为了方便后面处理,将y坐标比较高的那条线段列为第一条线段 swp(line1.a,line2.a); swp(line1.b,line2.b); } if(!dblcmp(line1.a.y-line1.b.y)||!dblcmp(line2.a.y-line2.b.y))ans=0.00;//如果有其中一条板是平行的,答案就是0; else{//不平行那么就属于其他的情况 if(judgecross(line1,line2))ans=solve(line1,line2); else ans=0.00; } printf("%.2lf\n",ans); } return 0;}
- poj 2826 Easy Problem
- POJ 2826 An Easy Problem?!
- poj 2826 An Easy Problem?!
- POJ 2826 An Easy Problem?!
- POJ 2826 An Easy Problem?!
- POJ 2826 An Easy Problem?!
- POJ 2826 An Easy Problem ?!
- POJ 2826 An Easy Problem?!
- Poj 2826 An Easy Problem!
- An Easy Problem?! - POJ 2826
- poj-2826 An Easy Problem?!
- POJ 2826 An Easy Problem?! 好题
- POJ 2826 An Easy Problem?!(计算几何)
- POJ 2826 An Easy Problem?!(计算几何)
- POJ 2826 An easy problem?! 几何基础
- POJ 2826 An Easy Problem 计算几何
- POJ 2826 An Easy Problem?! <计算几何>
- An Easy Problem?! POJ 2826 计算几何
- inWatch怎么样inWatch好不好
- inWatch怎么样inWatch好不好-机圈123
- 并查集路径压缩
- Cocos2d-x--使用Cocos2d-x v3.0.0
- 百度的一道笔试题
- poj 2826 Easy Problem
- linux的HZ, Tick, Jiffies
- SystemServer vs ServiceManager
- 多核多线程对int,float等类型的读原子性
- 白话经典算法系列之四 直接选择排序及交换二个数据的正确实现
- java_枚举类枚举值
- LOGFONT设置字体
- chrome html文档边框消除
- cf-337C Quiz