代码模板风格一般都不一样,主要还是看思路和实现思路吧
思路:
这题首先就是有三种为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