【POJ2451】Uyuw's Concert(半平面交)

传送门


不知道为什么,编译器用G++死活过不了,用C++直接过了。

迷惑。。。

半平面交复习题,无题解。


代码:

#include
#include
#include
#include
#define ll long long
#define re register
#define cs const

using std::cerr;
using std::cout;

cs double eps=1e-9;
struct Pnt{
	double x,y;Pnt(){}Pnt(cs double &_x,cs double &_y):x(_x),y(_y){}
	friend Pnt operator+(cs Pnt &a,cs Pnt &b){return Pnt(a.x+b.x,a.y+b.y);}
	friend Pnt operator-(cs Pnt &a,cs Pnt &b){return Pnt(a.x-b.x,a.y-b.y);}
	friend double operator*(cs Pnt &a,cs Pnt &b){return a.x*b.y-b.x*a.y;}
	friend Pnt operator*(cs Pnt &a,double b){return Pnt(a.x*b,a.y*b);}
};

inline int sign(double x){
	return (int)(x>-eps)-(x<eps);
}

struct Line{
	Pnt s,e;double rad;Line(){}
	Line(cs Pnt &_s,cs Pnt &_e):s(_s),e(_e),rad(atan2(e.y-s.y,e.x-s.x)){}
	friend bool operator<(cs Line &a,cs Line &b){
		return sign(a.rad-b.rad)?sign(a.rad-b.rad)<0:sign((a.e-a.s)*(b.e-a.s))>0;
	}
};

inline Pnt inter(cs Line &a,cs Line &b){
	double s1=(a.e-a.s)*(b.s-a.s);
	double s2=(b.e-a.s)*(a.e-a.s);
	double k=s1/(s1+s2);
	return b.s+(b.e-b.s)*k;
}

inline bool judge(cs Line &a,cs Line &b,cs Line &c){
	return sign((c.e-c.s)*(inter(a,b)-c.s))<0;
}

cs int N=5e4+50;
Line l[N<<1],q[N<<1];Pnt p[N];
int h,t,tot,n,m;

void half_plane_inter(){
	std::sort(l+1,l+m+1);n=0;
	for(int re i=1;i<=m;++i){
		if(i==1||sign(l[i].rad-l[i-1].rad))++n;
		l[n]=l[i];
	}m=n;n=0;q[h=1]=l[1],q[t=2]=l[2];
	for(int re i=3;i<=m;++i){
		while(h<t&&judge(q[t-1],q[t],l[i]))--t;
		while(h<t&&judge(q[h+1],q[h],l[i]))++h;
		q[++t]=l[i];
	}
	while(h<t&&judge(q[t-1],q[t],q[h]))--t;
	while(h<t&&judge(q[h+1],q[h],q[t]))++h;
	q[t+1]=q[h];n=0;
	for(int re i=h;i<=t;++i)p[++n]=inter(q[i],q[i+1]);
}

void Main(){
	scanf("%d",&m);double ans=0;
	for(int re i=1;i<=m;++i){
		double x1,y1,x2,y2;
		scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
		l[i]=Line(Pnt(x1,y1),Pnt(x2,y2));
	}l[++m]=Line(Pnt(0,0),Pnt(1e4,0));
	l[++m]=Line(Pnt(1e4,0),Pnt(1e4,1e4));
	l[++m]=Line(Pnt(1e4,1e4),Pnt(0,1e4));
	l[++m]=Line(Pnt(0,1e4),Pnt(0,0));
	half_plane_inter();p[n+1]=p[1];
	if(n>1)for(int re i=1;i<=n;++i)ans+=p[i]*p[i+1];
	printf("%.1f",ans/2);
}

void file(){
#ifdef zxyoi
	freopen("concert.in","r",stdin);
#endif
}
signed main(){file();Main();return 0;}

你可能感兴趣的:(半平面交)