BZOJ 1845三角形面积并

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1845

给定100个三角形,求三角形面积并。

戴神模板太可怕。直接调用函数秒掉。思路有点繁琐,不大清楚。贴一个代码。

代码:

/* ***********************************************
Author :rabbit
Created Time :2014/7/3 22:46:38
File Name :2.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
int dcmp(double x){
	if(fabs(x)<eps)return 0;
	return x>0?1:-1;
}
struct Point{
	double x,y;
	Point(double _x=0,double _y=0){
		x=_x;y=_y;
	}
};
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);
}
Point operator / (Point a,double p){
	return Point(a.x/p,a.y/p);
}
bool operator < (const Point &a,const Point &b){
	return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
bool operator == (const Point &a,const Point &b){
	return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Point a, Point b){
	return a.x*b.x+a.y*b.y;
}
double Length(Point a){
	return sqrt(Dot(a,a));
}
double Angle(Point a,Point b){
	return acos(Dot(a,b)/Length(a)/Length(b));
}
double angle(Point a){
	return atan2(a.y,a.x);
}
double Cross(Point a,Point b){
	return a.x*b.y-a.y*b.x;
}
Point GetLineIntersection(Point p,Point v,Point q,Point w){
	Point u=p-q;
	double t=Cross(w,u)/Cross(v,w);
	return p+v*t;
}
struct polygon{
	int n;
	Point p[100];
	double getarea(){
		double sum=0;
		for(int i=0;i<n;i++){
			sum+=Cross(p[i],p[(i+1)%n]);
		}
		return fabs(sum)/2;
	}
	bool getdir(){
		double sum=0;
		for(int i=0;i<n;i++)
			sum+=Cross(p[i],p[(i+1)%n]);
		if(dcmp(sum)>0)return 1;
		return 0;
	}
};
struct polygons{
	vector<polygon> p;
	polygons(){
		p.clear();
	}
	void push(polygon q){
		if(dcmp(q.getarea()))p.push_back(q);
	}
	vector<pair<double,int> > e;
	void ins(Point s,Point t,Point X,int i){
		double r=fabs(t.x-s.x)>eps?(X.x-s.x)/(t.x-s.x):(X.y-s.y)/(t.y-s.y);
		r=min(r,1.0);r=max(r,0.0);
		e.push_back(make_pair(r,i));
	}
	double polyareaunion(){
		double ans=0;
		int c0,c1,c2;
		for(int i=0;i<p.size();i++)
			if(p[i].getdir()==0)
				reverse(p[i].p,p[i].p+p[i].n);
		for(int i=0;i<p.size();i++){
			for(int k=0;k<p[i].n;k++){
				Point &s=p[i].p[k],&t=p[i].p[(k+1)%p[i].n];
				if(!dcmp(Cross(s,t)))continue;
				e.clear();
				e.push_back(make_pair(0.0,1));
				e.push_back(make_pair(1.0,-1));
				for(int j=0;j<p.size();j++)
					if(i!=j){
						for(int w=0;w<p[j].n;w++){
							Point a=p[j].p[w];
							Point b=p[j].p[(w+1)%p[j].n];
							Point c=p[j].p[(w-1+p[j].n)%p[j].n];
							c0=dcmp(Cross(t-s,c-s));
							c1=dcmp(Cross(t-s,a-s));
							c2=dcmp(Cross(t-s,b-s));
							if(c1*c2<0)ins(s,t,GetLineIntersection(s,t-s,a,b-a),-c2);
							else if(!c1&&c0*c2<0)ins(s,t,a,-c2);
							else if(!c1&&!c2){
								int c3=dcmp(Cross(t-s,p[j].p[(w+2)%p[j].n]-s));
								int dp=dcmp(Dot(t-s,b-a));
								if(dp&&c0)ins(s,t,a,dp>0?c0*((j>i)^(c0<0)):-(c0<0));
								if(dp&&c3)ins(s,t,b,dp>0?-c3*((j>i)^(c3<0)):c3<0);
							}
						}
					}
				sort(e.begin(),e.end());
				int ct=0;
				double tot=0,last;
				for(int j=0;j<e.size();j++){
					if(ct==1)tot+=e[j].first-last;
					ct+=e[j].second;
					last=e[j].first;
				}
				ans+=Cross(s,t)*tot;
			}
		}
		return fabs(ans)/2;
	}
};
int main()
{
     //freopen("data.in","r",stdin);
     //freopen("data.out","w",stdout);
     
	 int n;
	 while(~scanf("%d",&n)){
		 polygons ps;
		 double ans=0;
		 for(int i=0;i<n;i++){
			 polygon p1;
			 p1.n=3;
			 for(int j=0;j<p1.n;j++){
				 scanf("%lf%lf",&p1.p[j].x,&p1.p[j].y);
			 }
			 ps.push(p1);
		 }
		 printf("%.2f\n",ps.polyareaunion());
	 }
     return 0;
}


posted on 2019-03-31 19:34  xfgnongmin  阅读(78)  评论(0编辑  收藏  举报

导航