POJ 2826 An Easy Problem?!
2013-08-29 10:34
323 查看
题目还行,可惜自己不争气。
一开始就想到了所有情况:
1. 两条线不相交,不能装水。
2. 两条线重合 或 平行 不能装水。
3. 其中一条线水平放置,不能装水。
4. 如下图, 不能装水,同理两直线都向右斜时,也有这种情况
4. 把3中的图稍微改动一下,就能装水了,如下图
可见,先判断是不是1,2,3 这几种情况,如果不是,那么4,5这两种情况要再判断一下。
我想,这次不能再看别人的解题报告, 要自己做才能学到许多,尽管自己的方法不是很好,
以下思路纯自己构思,代码纯手写, 写得太乱, 太杂, 尽管做了一下午,每次都是测试了好几组数据才交, 还是16WA,但完全靠自己A了心情就是不一样,爽啊。
通过这题我学会了思考,不要过分依赖别人,当然自己A了以后可以看看别人的做法,这个是很有必要的。
我的奇葩AC代码:
View Code
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; #define eps 10e-8 struct point { double x, y; point(){} point(double xx, double yy) : x(xx), y(yy){}; }; struct seg { point a, b; seg(){} seg(point aa, point bb) : a(aa), b(bb){}; }s[3]; point p, tmp; int flag[3]; double cross(point o, point p1, point p2)//叉积 { return (p1.x - o.x)*(p2.y - o.y) - (p1.y - o.y)*(p2.x - o.x); } bool seg_cross(seg s1, seg s2)//判断线段是否相交 (规范相交 和 不规范相交,不考虑共线) { if(cross(s1.a, s1.b, s2.a) * cross(s1.a, s1.b, s2.b) <= eps && cross(s2.a, s2.b, s1.a) * cross(s2.a, s2.b, s1.b) <= eps) return 1; return 0; } point line_cross(seg u,seg v) //两直线求交点(标准模板) { point ret=u.a; double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x)) /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x)); ret.x+=(u.b.x-u.a.x)*t; ret.y+=(u.b.y-u.a.y)*t; return ret; } bool judge(seg s1, seg s2)//判断两线段是否平行 { if( (s1.a.y - s1.b.y)*(s2.a.x - s2.b.x) == (s2.a.y - s2.b.y)*(s1.a.x - s1.b.x) ) return 1; return 0; } int main() { int cas, i, j; scanf("%d", &cas); while(cas--) { for(i = 1; i <= 2 ;i++) scanf("%lf%lf%lf%lf",&s[i].a.x, &s[i].a.y, &s[i].b.x, &s[i].b.y); if(!seg_cross(s[1], s[2]) || s[1].a.y == s[1].b.y || s[2].a.y == s[2].b.y ||judge(s[1], s[2])) //1,2这两种情况 { printf("0.00\n"); continue;} //求两线段交点,并去除交点以下的线段 p = line_cross(s[1], s[2]); for(i = 1; i <= 2; i++) { if( s[i].a.y < s[i].b.y || s[i].a.y == s[i].b.y && s[i].a.x < s[i].b.x ) swap(s[i].a, s[i].b); //把线段中 点y值大的移到 线段的a端点 s[i].b = p; //b端变为交点 } if(s[1].a.y > s[2].a.y )swap(s[1], s[2]); //把线段a端y值大的移到水线段s[1]去 if( (s[1].a.x - p.x) * (s[1].a.y - p.y) * (s[2].a.x - p.x) * (s[2].a.y - p.y) > -eps)//判断两直线斜率相乘是否大于0,除法和乘法正负性不变,就是4,5的情况和跟4,5对称的情况 { if(seg_cross( seg( s[1].a, point(s[1].a.x, s[2].a.y) ), s[2])) //判断线段a端y值比较小的 线段 向上延长 跟 另一条线段是否相交,相交就说明 上面的板盖住了下面的板, 不能装水 。 {printf("0.00\n"); continue;} } // 剩下的情况都可以装水, 根据木桶效应,两个线段的高度应该取 两个之中最低的 if(s[1].a.y > s[2].a.y) s[1].a = line_cross( s[1], seg( point(0, s[2].a.y), point(1, s[2].a.y)) ); else if(s[1].a.y < s[2].a.y) s[2].a = line_cross( s[2], seg( point(0, s[1].a.y), point(1, s[1].a.y)) ); //计算面积 printf("%.2f\n", (s[1].a.y - p.y) * fabs((s[1].a.x - s[2].a.x))/2); } return 0; }
相关文章推荐
- POJ 2826 An Easy Problem?! --计算几何,叉积
- poj 2826 An Easy Problem?! (线段相交问题终极版...并不easy)
- POJ 2826 An Easy Problem?! <计算几何>
- POJ 2826 || an easy problem ?!(未AC,呵呵~
- 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?!
- 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?!
- An Easy Problem?! POJ - 2826 (几何)