题目链接:
http://poj.org/problem?id=2826
题目大意:
给两条线段,然后有雨水落下来,问这两条线段组成的容器里面最多放置水的面积。
思路:
如果线段不相交,或者有一条线段是与x轴平行的,那么肯定不能容下水。能盛下水的情况就是两线段相交,然后有2个点在交点上方。但是有一种情况是,从y轴往下看的时候,有一条线段完全覆盖住了另一条,这个时候也是没有水进入的。
搞清楚情况以后,就是模拟了。
代码:
#include
#include
#include
#include
#define eps 1e-8
using namespace std;
struct Point{
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
};
struct line{
Point a,b;
line(Point a=0,Point b=0):a(a),b(b){}
};
Point p[10005],ch[10005];
line Line[5005];
Point operator + (Point A ,Point B){
return Point(A.x+B.x,A.y+B.y);
}
Point operator - (Point A,Point B){
return Point(A.x-B.x,A.y-B.y);
}
Point operator * (Point A,double p){
return Point(A.x*p,A.y*p);
}
bool operator < (const Point &a,const Point &b){
return a.xP.y){
tt++;
if(i==1||i==2){A=p[i];ff=1;}
else B=p[i];
}
}
if(tt<2){
printf("0.00\n");
continue;
}
if(p[1].x!=p[2].x&&p[3].x!=p[4].x){
k1=(p[2].y-p[1].y)/(p[2].x-p[1].x);
k2=(p[4].y-p[3].y)/(p[4].x-p[3].x);
}
else {
if(p[1].x==p[2].x&&p[3].x==p[4].x)printf("0.00\n");
else {
if(!SegmentProperIntersection(p[1],p[2],p[3],p[4])&&!(P==p[1])&&!(P==p[2])&&!(P==p[3])&&!(P==p[4])){
printf("0.00\n");
continue;
}
if(p[1].x==p[2].x){
if(A.y>B.y){
Point pp=intersection(l1,line(B,Point(B.x-1,B.y)));
S=(pp.y-P.y)*(B.x-pp.x)*0.5;
}
else {
Point pp=intersection(l2,line(A,Point(A.x-1,A.y)));
S=(pp.y-P.y)*(A.x-pp.x)*0.5;
}
}
else if(p[3].x==p[4].x){
if(B.y>A.y){
Point pp=intersection(l2,line(A,Point(A.x-1,A.y)));
S=(pp.y-P.y)*(A.x-pp.x)*0.5;
}
else {
Point pp=intersection(l1,line(B,Point(B.x-1,B.y)));
S=(pp.y-P.y)*(B.x-pp.x)*0.5;
}
}
printf("%.2f\n",fabs(S)+eps);
}
continue;
}
if(SegmentProperIntersection(p[1],p[2],p[3],p[4])||(P==p[1]||P==p[2]||P==p[3]||P==p[4])){
// printf("**\n");
int ff=0;
for(i=1;i<=4;i++){
if(p[i].y>P.y){
tt++;
if(i==1||i==2){A=p[i];ff=1;}
else B=p[i];
}
}
if(tt<2){
printf("0.00\n");
continue;
}
else {
if(k1*k2<0){
if(A.y0){
//printf("#$%\n");
if(k1>k2){
if(A.y>B.y){
Point tmp=intersection(l2,line(A,Point(A.x,A.y-1)));
tmp.y-=1;
if(SegmentProperIntersection(p[3],p[4],A,tmp)){
Point pp=intersection(l1,line(B,Point(B.x-1,B.y)));
S=(B.x-pp.x)*(B.y-P.y)*0.5;
printf("%.2f\n",fabs(S)+eps);
}
else {
printf("0.00\n");
continue;
}
}
else {
Point pp=intersection(l2,line(A,Point(A.x-1,A.y)));
S=(A.x-pp.x)*(A.y-P.y)*0.5;
printf("%.2f\n",fabs(S)+eps);
}
}
else {
if(B.y>A.y){
Point tmp=intersection(l1,line(B,Point(B.x,B.y-1)));
tmp.y-=1;
if(SegmentProperIntersection(p[1],p[2],B,tmp)){
Point pp=intersection(l2,line(A,Point(A.x-1,A.y)));
S=(A.x-pp.x)*(A.y-P.y) *0.5;
printf("%.2f\n",fabs(S)+eps);
}
else {
printf("0.00\n");
continue;
}
}
else {
Point pp=intersection(l1,line(B,Point(B.x-1,B.y)));
S=(B.x-pp.x)*(B.y-P.y)*0.5;
printf("%.2f\n",fabs(S)+eps);
}
}
}
else {
if(k1B.y){
Point tmp=intersection(l2,line(A,Point(A.x,A.y-1)));
tmp.y-=1;
if(SegmentProperIntersection(p[3],p[4],A,tmp)){
Point pp=intersection(l1,line(B,Point(B.x-1,B.y)));
S=(B.x-pp.x)*(B.y-P.y)*0.5;
printf("%.2f\n",fabs(S)+eps);
}
else {
printf("0.00\n");
continue;
}
}
else {
Point pp=intersection(l2,line(A,Point(A.x-1,A.y)));
S=(pp.x-A.x)*(A.y-P.y)*0.5;
printf("%.2f\n",fabs(S)+eps);
}
}
else {
// printf("#$\n");
if(B.y>A.y){
Point tmp=intersection(l1,line(B,Point(B.x,B.y-1)));
tmp.y-=1;
if(SegmentProperIntersection(p[1],p[2],B,tmp)){
Point pp=intersection(l2,line(A,Point(A.x-1,A.y)));
S=(A.x-pp.x)*(A.y-P.y) *0.5;
printf("%.2f\n",fabs(S)+eps);
}
else {
printf("0.00\n");
continue;
}
}
else {
Point pp=intersection(l1,line(B,Point(B.x-1,B.y)));
S=(pp.x-B.x)*(B.y-P.y)*0.5;
printf("%.2f\n",fabs(S)+eps);
}
}
}
}
}
}
else {
printf("0.00\n");
continue;
}
}
}
/*
1 1 1 4
0 0 2 3
*/