POJ - 2826 An Easy Problem?(附带大概ac的数据)

链接:An Easy Problem?!

代码模板风格一般都不一样,主要还是看思路和实现思路吧

思路:

这题首先就是有三种为0的情况

1.线段不相交

2.长的挡到下面短的(重要

3.还有很多不需要特殊处理的情况,比如有一个平行于x轴,伞状相交等

怎么判断线段相交

我是两次判断直线和线段相交,线段分别作为一次直线和线段,也可以用网上其他的代码

基本思路

找出两个线段y值最高的点,再从两个y值高的中找出最高的点,低的两个点就不用了

怎么判断长的挡到下面短的

高点中的低点交点高点中的高点的直线左边或右边

且判断三个点的x大小

求最后的面积

=(高点,低点,交点的三角形面积)*(低点y-交点y)/(高点y-交点y)

很多人说最后要+EXP(也就是一个很小的数比如1e-8),其实不加我的也能过

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
#define fo(a,b) for(int i=a;i<=b;i++)
#define ll long long
#define dou double
#define EXP 1e-8
#define M 1005
#define ll long long
int t;
dou sum;
struct P{
    double x,y,da;
    P(double x=0,double y=0):x(x),y(y){}
    bool operator<(const P temp)const{
        if(y==temp.y) return x<temp.x;
        return y<temp.y;
    }
};
struct L{
    P a,b;
    L(){}
    L(P a,P b):a(a),b(b){}
}l,r;
double area(P a,P b,P c){
    return fabs((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y))/2;
}
bool par(L a,L b){
    return fabs((a.b.x-a.a.x)*(b.b.y-b.a.y)-(b.b.x-b.a.x)*(a.b.y-a.a.y))<EXP;
}
dou cross(P mark,P a,P b){             //在向量a->b的左边
    return (a.x-mark.x)*(b.y-mark.y)-(b.x-mark.x)*(a.y-mark.y);
}
int inte(L x,P a,P b)               //x是直线,a和b是线段两端点
{
    return cross(a,x.a,x.b)*cross(b,x.a,x.b)<EXP;
}
P find(L x,L y)
{
    dou k=area(x.a,y.a,y.b)/(area(x.b,y.a,y.b)+area(x.a,y.a,y.b));
    return P(x.a.x+(x.b.x-x.a.x)*k,x.a.y+(x.b.y-x.a.y)*k);
}
int f(L x,L y){
    if(par(x,y)) return 0;
    return inte(x,y.a,y.b)&&inte(y,x.a,x.b);
}
signed main()
{
    cin>>t;
    while(t--){
        sum=0;
        scanf("%lf%lf%lf%lf",&l.a.x,&l.a.y,&l.b.x,&l.b.y);
        scanf("%lf%lf%lf%lf",&r.a.x,&r.a.y,&r.b.x,&r.b.y);
        if(f(l,r)){
            P res=find(l,r);
            if(l.a<l.b) swap(l.a,l.b);        //找出l线段最高点
            if(r.a<r.b) swap(r.a,r.b);        //找出r线段最高点
            if(r.a<l.a) swap(l.a,r.a);        //找出最高点的最高点
            if((r.a.x<=l.a.x&&l.a.x<=res.x&&cross(l.a,res,r.a)>EXP)||(res.x<=(l.a.x)&&l.a.x<=r.a.x&&cross(l.a,res,r.a)<-EXP)){}        //长的挡到下面短的
            else if((r.a.y-res.y)>EXP) sum=area(res,l.a,r.a)*((l.a.y-res.y)/(r.a.y-res.y));
        }
        printf("%.2lf\n",sum);
    }
    return 0;
}

 相信很多人WA

数据

100
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

1 1 7 7
7 7 15 15

0 0 -1 -1
0 0 1 -1

答案:https://paste.ubuntu.com/p/Rh6md6mk4v/

猜你喜欢

转载自blog.csdn.net/m0_58177653/article/details/123791883