码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2826 An Easy Problem?!(计算几何)

时间:2015-08-06 02:04:03      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:poj 2826 an easy pro   计算几何   

An Easy Problem?!
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10533   Accepted: 1589

Description

It‘s raining outside. Farmer Johnson‘s bull Ben wants some rain to water his flowers. Ben nails two wooden boards on the wall of his barn. Shown in the pictures below, the two boards on the wall just look like two segments on the plane, as they have the same width. 
技术分享

Your mission is to calculate how much rain these two boards can collect. 

Input

The first line contains the number of test cases. 
Each test case consists of 8 integers not exceeding 10,000 by absolute value, x1y1x2y2x3y3x4y4. (x1y1), (x2y2) are the endpoints of one board, and (x3y3), (x4y4) are the endpoints of the other one. 

Output

For each test case output a single line containing a real number with precision up to two decimal places - the amount of rain collected. 

Sample Input

2
0 1 1 0
1 0 2 1

0 1 2 1
1 0 1 2

Sample Output

1.00
0.00

Source

题意:就是两根木块组成一个槽,问槽里能装多少雨水。

题解:基本情况:不相交、相交、相交且覆盖(高的那块板挡住雨水入口)。

#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<vector>
#define N 100010
#define inf 99999999999.0

using namespace std;

struct Point {
    double x,y;
} ;

int n;

double multi(Point p0,Point p1,Point p2) {
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

bool is_inter(Point s1,Point e1,Point s2,Point e2) {
    return (max(s1.x,e1.x)>=min(s2.x,e2.x))&&
           (max(s2.x,e2.x)>=min(s1.x,e1.x))&&
           (max(s1.y,e1.y)>=min(s2.y,e2.y))&&
           (max(s2.y,e2.y)>=min(s1.y,e1.y))&&
           (multi(s1,s2,e1)*multi(s1,e1,e2)+1e-15>=0)&&
           (multi(s2,s1,e2)*multi(s2,e2,e1)+1e-15>=0);
}

Point jd(Point u1,Point u2,Point v1,Point v2) {
    Point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
             /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}

int main() {
    //freopen("test.in","r",stdin);
    int  t;
    cin>>t;
    while(t--) {
        Point p[5];
        scanf("%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[2].x,&p[2].y);
        scanf("%lf%lf%lf%lf",&p[3].x,&p[3].y,&p[4].x,&p[4].y);
        if(!is_inter(p[1],p[2],p[3],p[4])) {
            printf("0.00\n");
            continue;
        }
        Point it=jd(p[1],p[2],p[3],p[4]);
        Point a[3];
        int num=0;///高于交点it.y的点的个数
        for(int i=1; i<5; i++) {
            if(p[i].y>it.y) {
                num++;
                a[num]=p[i];
            }
        }
        //printf("num=%d\n",num);
        if(num<2) {
            printf("0.00\n");
            continue;
        }
        double ans=0;

        if(a[1].y>a[2].y) {///第一块板高于第二块板
            if(fabs(a[1].x-it.x)<1e-15) {
                ans=fabs(a[1].x-a[2].x)*fabs(it.y-a[2].y)/2;
            } else {
                double k=(a[1].y-it.y)/(a[1].x-it.x); ///a[1]->it的斜率
                double b=a[1].y-k*a[1].x;
                double x=(a[2].y-b)/k;     //a[1]->it上纵坐标为a[2].y的横坐标
                ans=fabs(a[2].y-it.y)*fabs(a[2].x-x)/2;
            }
            Point pp;
            pp.x=a[2].x;
            pp.y=1000000.0;
            if(is_inter(a[1],it,a[2],pp))///覆盖
                ans=0.0;
        } else {
            if(fabs(a[2].x-it.x)<1e-15) {
                ans=fabs(a[1].x-a[2].x)*fabs(it.y-a[1].y)/2;
            } else {
                double k=(a[2].y-it.y)/(a[2].x-it.x);
                double b=a[2].y-k*a[2].x;
                double x=(a[1].y-b)/k;
                ans=fabs(a[1].y-it.y)*fabs(a[1].x-x)/2;
            }
            Point pp;
            pp.x=a[1].x;
            pp.y=1000000.0;
            if(is_inter(a[2],it,a[1],pp))
                ans=0.0;
        }
        printf("%.2f\n",ans);
    }
    return 0;
}

/*
9
6259 2664 8292 9080
1244 2972 9097 9680

0 1 1 0
1 0 2 1

0 1 2 1
1 0 1 2

0 0 10 10
0 0 9 8

0 0 10 10
0 0 8 9

0.9 3.1 4 0
0 3 2 2

0 0 0 2
0 0 -3 2

1 1 1 4
0 0 2 3

1 2 1 4
0 0 2 3


*/
/*
  6162.65
  1.00
  0.00
  0.00
  4.50
  0.50
  3.00
  0.75
  0.00
*/


版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 2826 An Easy Problem?!(计算几何)

标签:poj 2826 an easy pro   计算几何   

原文地址:http://blog.csdn.net/acm_baihuzi/article/details/47307773

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!