题目大意:有两块木板交叉起来接雨水,问最多能接多少。
 
分析:题目描述很简单,不过有些细节还是需要注意到,如下图几种情况:
 
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN = ;
const double oo = 1e4+;
const double EPS = 1e-; int sign(double val)
{
if(val > EPS)return ;
if(fabs(val) < EPS)return ;
return -;
} struct Point
{
double x, y;
Point(double x=, double y=):x(x), y(y){}
Point operator - (const Point &tmp) const{
return Point(x-tmp.x, y-tmp.y);
}
double operator ^(const Point &tmp) const{
return x*tmp.y - y*tmp.x;
}
bool operator == (const Point &tmp) const{
return fabs(x-tmp.x) < EPS && fabs(y-tmp.y) < EPS;
}
double operator *(const Point &tmp) const{
return x*tmp.x + y*tmp.y;
}
};
struct Segment
{
Point s, e;
double a, b, c;///ax + by = c
Segment(Point s=, Point e=):s(s), e(e){
a = s.y - e.y;
b = e.x - s.x;
c = e.x*s.y - s.x*e.y;
}
bool Inter(const Segment &t)const{
int v1 = sign((s-e)^(t.s-e));
int v2 = sign((s-e)^(t.e-e)); if(!v1 && !v2)return false;///共线 if(!v1 && t.s.x >= min(s.x, e.x) && t.s.x <= max(s.x, e.x)
&& t.s.y >= min(s.y, e.y) && t.s.y <= max(s.y, e.y)
|| !v2 && t.e.x >= min(s.x, e.x) && t.e.x <= max(s.x, e.x)
&& t.e.y >= min(s.y, e.y) && t.e.y <= max(s.y, e.y)
|| v1 * v2 == -)return true; return false;
}
Point CrossNode(const Segment &t) const{
Point ans;
ans.x = (c*t.b-t.c*b)/(a*t.b-t.a*b);
ans.y = (c*t.a-t.c*a)/(b*t.a-t.b*a); return ans;
}
};
double Dist(Point a, Point b)
{
return sqrt((a-b) * (a-b));
}
double Find(Point crs, Point p[], int N)
{
double sum = ; for(int i=; i<N; i++)
for(int j=i+; j<N; j++)
{
int k = sign((p[i]-crs)^(p[j]-crs)); if(p[i] == p[j])continue; if(crs.x>=min(p[i].x, p[j].x) && crs.x<=max(p[i].x, p[j].x)
|| crs.x>=p[i].x && crs.x>=p[j].x && (k>&&(p[i].x-p[j].x>EPS) || k<&&(p[j].x-p[i].x>EPS))
|| crs.x<=p[i].x && crs.x<=p[j].x && (k<&&(p[j].x-p[i].x>EPS) || k>&&(p[i].x-p[j].x>EPS)))
if(p[i].y-crs.y > EPS && p[j].y-crs.y > EPS)
{
Point A = p[i].y < p[j].y ? p[i] : p[j];
Point B = (A == p[i] ? p[j] : p[i]);
Segment t1(Point(-oo, A.y), Point(oo, A.y));
Segment t2(crs, B); B = t1.CrossNode(t2); double La = Dist(A, B);
double Lb = Dist(A, crs);
double Lc = Dist(B, crs);
double p = (La+Lb+Lc) / ; sum += sqrt(p*(p-La)*(p-Lb)*(p-Lc));
}
} return sum;
} int main()
{
int T; scanf("%d", &T); while(T--)
{
Point p[MAXN], crs; scanf("%lf%lf%lf%lf", &p[].x, &p[].y, &p[].x, &p[].y);
scanf("%lf%lf%lf%lf", &p[].x, &p[].y, &p[].x, &p[].y);
Segment L1(p[], p[]), L2(p[], p[]); double ans = ; if(L1.Inter(L2) && L2.Inter(L1))
{
crs = L1.CrossNode(L2);
ans = Find(crs, p, );
} printf("%.2f\n", ans+EPS);
} return ;
}

An Easy Problem?! - POJ 2826(求面积)的更多相关文章

  1. POJ 1152 An Easy Problem! (取模运算性质)

    题目链接:POJ 1152 An Easy Problem! 题意:求一个N进制的数R.保证R能被(N-1)整除时最小的N. 第一反应是暴力.N的大小0到62.发现当中将N进制话成10进制时,数据会溢 ...

  2. hdu2601 An easy problem(数学)

    题目意思: http://acm.hdu.edu.cn/showproblem.php? pid=2601 给出一个数N,求N=i*j+i+j一共同拥有多少种方案. 题目分析: 此题直接暴力模拟就可以 ...

  3. POJ 2826 An Easy Problem?![线段]

    An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12970   Accepted: 199 ...

  4. POJ 2826 An Easy Problem? 判断线段相交

    POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...

  5. POJ 2826 An Easy Problem?!

    An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7837   Accepted: 1145 ...

  6. POJ 2826 An Easy Problem?! --计算几何,叉积

    题意: 在墙上钉两块木板,问能装多少水.即两条线段所夹的中间开口向上的面积(到短板的水平线截止) 解法: 如图: 先看是否相交,不相交肯定不行,然后就要求出P与A,B / C,D中谁形成的向量是指向上 ...

  7. POJ 2826 An Easy Problem?! 好的标题

    受该两块木板以形成槽的效果.Q槽可容纳雨水多,注意雨爆跌,思想是非常easy,分类讨论是有点差. 1.假定两条线段不相交或平行,然后再装0: 2.有一个平行x轴.连衣裙0. 3.若上面覆盖以下的,装0 ...

  8. 【解题报告】PKU 2826 An Easy Problem?!

    原题链接:http://poj.org/problem?id=2826 一题很蛋疼的一题.目前为止还有一个问题我没搞清楚,问题注在代码中. 题目大意: 外面下雨了,农民Johnoson的bull(?? ...

  9. poj 3348--Cows(凸包求面积)

    链接:http://poj.org/problem?id=3348 Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions:  ...

随机推荐

  1. JAVA zip解压 MALFORMED 错误

    最近在在使用zip 解压时,使用JDK1.7及以上版本在解压时,某些文件会报异常 Exception in thread "main" java.lang.IllegalArgum ...

  2. C# 进程 和线程

    进程 没有应用程序可以看做是一个进程 线程:就是对cpu执行的最小单位 单线程:前台线程和后台线程 带来的问题:假死 net中不能跨线程访问

  3. PHP设计模式之:工厂模式

    工厂模式: 由工厂类根据参数来决定创建出哪一种产品类的实例: 工厂类是指包含了一个专门用来创建其他对象的方法的类.所谓按需分配,传入参数进行选择,返回具体的类.工厂模式的最主要作用就是对象创建的封装. ...

  4. c++预编译问题:fatal error C1083: Cannot open precompiled header file: 'Debug/DllTest.pch': No such file or d

    1)单独编译StdAfx.cpp 2)编译所有(即按Ctrl+F7) 这时因为该模块没有包括预编译头文件“stdafx.h”的缘故.VC用一个stdafx.cpp包含头文件stdafx.h,然后在st ...

  5. 分享一个自己写的基于TP的关系模型

    为了说明问题,假设现在有表test1,test1有从表test2:test1属于test3,test1和test4多对多,关联表test1_test4. 1.定义关系 class Test1Model ...

  6. MVVM模式应用 之加载Pivot的数据

    在Pivot布局里,在进入页面时,不想页面数据全部加载,而是移动到哪个privotItem,加载那个privotItem的值. 这时我们先给pivot绑定一个command. <phone:Pi ...

  7. tomcat gc问题总结

    Java内存泄露监控工具:JVM监控工具介绍  http://developer.51cto.com/art/201203/321431.htm 关于施用full gc频繁的分析及解决  http:/ ...

  8. 安装sql server 2008,提示要删除SQL Server 2005 Express 工具 怎么解决?

    x86 修改注册表:HKLM\Software\Microsoft\Microsoft SQL Server\90\Tools\ShellSEM,把 ShellSEM重命名即可. x64       ...

  9. Shortcut Collapse project or projects in the Solution Explorer Microsoft Visual Studio 2008

    The standard windows keyboard shortcuts for expanding and collapsing treeviews are: Numeric Keypad * ...

  10. C++编译器合成Default Constructor的4种情况

    笔记C++编译器为编译器需要合成Default Constructor的4种情况. 1,Class A内含Class B对象,Class A没有Default Constructor时会在编译时合成D ...