POJ 2826 An Easy Problem?! 好的标题
受该两块木板以形成槽的效果。Q槽可容纳雨水多,注意雨爆跌,思想是非常easy,分类讨论是有点差。
1.假定两条线段不相交或平行,然后再装0; 
2.有一个平行x轴。连衣裙0。 
3.若上面覆盖以下的,装0; 
4.其他,叉积求面积。
直接上代码:
#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
const double eps=1e-8;
struct point{
    double x;
    double y;
};
struct line{
    point a;
    point b;
}l1,l2;
double ans;
//求叉积
double xmult(point p0 ,point p1 ,point p2){
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int dblcmp(double n){
    if(fabs(n)<eps) return 0;
    return n>0?1:-1;
 }
//推断是否相交。怎样相交
int judge(line l1 ,line l2){
    double d1=dblcmp(max(l1.a.x,l1.b.x)-min(l2.a.x,l2.b.x));
    double d2=dblcmp(max(l2.a.x,l2.b.x)-min(l1.a.x,l1.b.x));
    double d3=dblcmp(max(l1.a.y,l1.b.y)-min(l2.a.y,l2.b.y));
    double d4=dblcmp(max(l2.a.y,l2.b.y)-min(l1.a.y,l1.b.y));
    double d5=dblcmp(xmult(l2.a,l1.a,l1.b));
    double d6=dblcmp(xmult(l2.b,l1.a,l1.b));
    double d7=dblcmp(xmult(l1.a,l2.a,l2.b));
    double d8=dblcmp(xmult(l1.b,l2.a,l2.b));
    if(d1>=0&&d2>=0&&d3>=0&&d4>=0){
        if(d5*d6>0||d7*d8>0) return 0;//不相交
        else if(d5==0&&d6==0) return 1;//共线相交
        else if(d5==0||d6==0||d7==0||d8==0) return 2;//端点相交
        else return 3;//规范相交
    }
    return 0;
}
//求斜率
bool getslope(line l ,double &k){
    double t=l.a.x-l.b.x;
    if(t==0) return false;
    k=(l.a.y-l.b.y)/t;
    return true;
}
//求线段交点
point getIntersect(line l1, line l2) {
    point p;
    double A1 = l1.b.y - l1.a.y;
    double B1 = l1.a.x - l1.b.x;
    double C1 = (l1.b.x - l1.a.x) * l1.a.y - (l1.b.y - l1.a.y) * l1.a.x;
    double A2 = l2.b.y - l2.a.y;
    double B2 = l2.a.x - l2.b.x;
    double C2 = (l2.b.x - l2.a.x) * l2.a.y - (l2.b.y - l2.a.y) * l2.a.x;
    p.x = (C2*B1 - C1*B2) / (A1*B2 - A2*B1);
    p.y = (C1*A2 - C2*A1) / (A1*B2 - A2*B1);
    if(p.x==-0) p.x=0;
    return p;
 }
 //求a,b两点中y坐标更大的点
 point getbiggerY(point a ,point b){
     point q;
     if (dblcmp(a.y-b.y) > 0) {
        q.x = a.x;
        q.y = a.y;
    } else {
        q.x = b.x;
        q.y = b.y;
    }
     return q;
 }
double getarea(point p ,point p1 ,point p2){
    point q;
    double a;
    if(dblcmp(p1.y-p2.y)>=0) {
        q.y = p2.y;
        q.x = p.x+(p1.x-p.x)*(p2.y-p.y) / (p1.y-p.y); //求还有一点的坐标
        a=fabs(xmult(p, p2, q)) / 2; //叉积求面积
    }
    else {
        q.y = p1.y;
        q.x = p.x+(p2.x-p.x)*(p1.y-p.y) / (p2.y-p.y);
        a=fabs(xmult(p, p1, q)) / 2;
    }
    return a;
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        point p1 ,p2 ,p;
        cin>>l1.a.x>>l1.a.y>>l1.b.x>>l1.b.y;
        cin>>l2.a.x>>l2.a.y>>l2.b.x>>l2.b.y;
        if(judge(l1,l2)<=1)//是否相交
            ans=0;
        else{
            p1=getbiggerY(l1.a ,l1.b);
            p2=getbiggerY(l2.a ,l2.b);
            p=getIntersect(l1 ,l2);
            if(!dblcmp(p.x-p1.x)&&!dblcmp(p.y-p1.y) || !dblcmp(p.x-p2.x)&&!dblcmp(p.x-p2.y))//开口方向
                   ans=0;
            else{
                double k1 ,k2;
                bool f1 ,f2;
                f1 = getslope(l1, k1);
                f2 = getslope(l2, k2);
                if (!dblcmp(k1) || !dblcmp(k2)) ans=0;
                else if (f1 && f2) {//假设两条线都不与y轴平行
                    if (dblcmp(k1*k2) > 0) { //当两条线段的斜率符号同样时。
                        int d1 = dblcmp(k1-k2);
                        int d2 = dblcmp(k2);
                        if (d1>0&&d2>0&&dblcmp(p2.x-p1.x)*dblcmp(p2.x-p.x)<=0
                            || d1<0&&d2>0&&dblcmp(p1.x-p2.x)*dblcmp(p1.x-p.x)<= 0
                            || d1>0&&d2<0&&dblcmp(p1.x-p2.x)*dblcmp(p1.x-p.x)<= 0
                            || d1<0&&d2<0&&dblcmp(p2.x-p1.x)*dblcmp(p2.x-p.x)<= 0)//覆盖情况
                            ans = 0;
                        else
                          ans=getarea(p,p1,p2);
                        }
                    else
                        ans=getarea(p,p1,p2);
                    }
                else
                        ans=getarea(p,p1,p2);
            }
        }
        printf ("%.2lf\n", ans);
    }
    return 0;
}
版权声明:本文博客原创文章。博客,未经同意,不得转载。
POJ 2826 An Easy Problem?! 好的标题的更多相关文章
- POJ 2826 An Easy Problem? 判断线段相交
		
POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...
 - POJ 2826 An Easy Problem?!
		
An Easy Problem?! Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7837 Accepted: 1145 ...
 - POJ 2826 An Easy Problem?![线段]
		
An Easy Problem?! Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12970 Accepted: 199 ...
 - POJ 2826 An Easy Problem?! --计算几何,叉积
		
题意: 在墙上钉两块木板,问能装多少水.即两条线段所夹的中间开口向上的面积(到短板的水平线截止) 解法: 如图: 先看是否相交,不相交肯定不行,然后就要求出P与A,B / C,D中谁形成的向量是指向上 ...
 - POJ 2826  An Easy Problem!(简单数论)
		
Description Have you heard the fact "The base of every normal number system is 10" ? Of co ...
 - 简单几何(线段相交) POJ 2826 An Easy Problem?!
		
题目传送门 题意:两条线段看成两块木板,雨水从上方往下垂直落下,问能接受到的水的体积 分析:恶心的分类讨论题,考虑各种情况,尤其是入口被堵住的情况,我的方法是先判断最高的两个点是否在交点的同一侧,然后 ...
 - POJ 2826 An Easy Problem?!(线段交点+简单计算)
		
Description It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Be ...
 - POJ 1152 An Easy Problem! (取模运算性质)
		
题目链接:POJ 1152 An Easy Problem! 题意:求一个N进制的数R.保证R能被(N-1)整除时最小的N. 第一反应是暴力.N的大小0到62.发现当中将N进制话成10进制时,数据会溢 ...
 - [POJ] 2453 An Easy Problem [位运算]
		
An Easy Problem Description As we known, data stored in the computers is in binary form. The probl ...
 
随机推荐
- Codeforces Round #112 (Div. 2)---A. Supercentral Point
			
Supercentral Point time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
 - Web端server推送技术原理分析及dwr框架简单的使用
			
1 背景 "server推送技术"(ServerPushing)是近期Web技术中最热门的一个流行术语.它是继"Ajax"之后又一个倍受追捧的Web技术.&qu ...
 - 【linux】开发环境说明
			
欢迎转载,转载时请保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http:// ...
 - Servlet的学习之Session(4)
			
在本篇中,我们来使用Session完成一个用户登录的案例,前提声明:这个案例主要用于学习Session技术,是属于比较简单的类型,以后会采用MVC模式来开发登录,那就会比较复杂. 现在大多数网站都提供 ...
 - SuperSocket应用之FTP源码解析
			
一 简述 命令行协议是一种使用比较多的协议,其优点在于使用简单易于扩展性,同时也利于解析和使用.FTP,POP,SMTP等均采用命令行协议,其中FTP在早起互联网时期成为网络资源共享的主要方式,可见F ...
 - 奇怪的问题,InvalidateRect最后一个参数在XP下无效
			
一直用的WIN2K系统,写的一个程序在本机正常,到XP系统的机器运行发现调整窗口大小时界面闪得厉害,程序比较大,而且这种闪烁还不好调试,因为单步调试没有闪烁效果,只能排除法找原因,最后以为找到原因了, ...
 - Qt Style Sheets Examples(QT真是有很全的文档)
			
http://doc.qt.io/qt-5/stylesheet-examples.html http://doc.qt.io/qt-4.8/stylesheet.html
 - Swift - 计算次方(2的N次方,2的随机次方)
			
1,使用<<计算2的N次方 1 2 var value = 1<<4 //2的4次方 var value = 1<<Int(arc4random_uniform( ...
 - 重复数据删除(De-duplication)技术研究(SourceForge上发布dedup util)
			
dedup util是一款开源的轻量级文件打包工具,它基于块级的重复数据删除技术,可以有效缩减数据容量,节省用户存储空间.目前已经在Sourceforge上创建项目,并且源码正在不断更新中.该工具生成 ...
 - map标签的详细使用参数
			
map标签必须成对出现,即 <map> ....</map> 同时map必须和area配合使用. img标签里的usermap属性值必须与map标签里的id和name值完全一致 ...