const double eps = 1e-9;
struct Point
{
int x, y;
Point(){}
Point(int x, int y):x(x),y(y){}
Point operator - (Point &b)
{
return Point(x-b.x, y-b.y);
}
bool operator < (Point p)
{
if(y!=p.y) return y<p.y;
return x<p.x;
}
};
int sgn(int d)
{
if(d<eps) return -1;
return d>eps;
}
int dcmp(double x,double y)
{
if(fabs(x - y) < eps) return 0;
if(x > y) return 1;
return -1;
}
double Cross(Point A, Point B) return A.x*B.y-A.y*B.x;
double Dot(Point A, Point B) return A.x*B.x + A.y*B.y;
bool OnSegment(Point p, Point a1, Point a2)
{
return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
}
double PolygonArea(vector<Point> p)
{
int n = p.size();
double s = 0;
for(int i = 1; i < n-1; ++i)
s += Cross(p[i]-p[0], p[i+1]-p[0]);
return s;
}
int isPointInPolygon(Point p,vector<Point> con)
{
int k = con.size();
if(k<3) return 0;
if(Cross(p-con[0],con[1]-con[0])>-eps) return 0;
if(Cross(p-con[0],con[k-1]-con[0])<eps) return 0;
int i=2,j=k-1;
int line=-1;
while(i<=j)
{
int mid=(i+j)>>1;
if(Cross(p-con[0],con[mid]-con[0])>-eps)
{
line=mid;
j=mid-1;
}
else i=mid+1;
}
if(line>0)
return Cross(p-con[line-1],con[line]-con[line-1])<-eps;
return 0;
}
vector<Point> ConvexHull(vector<Point> p)
{
t = p.size(); if(t<=1) return p;
sort(p.begin(), p.end());
vector<Point> q(t*2); int k = 0;
for(register int i=0; i<t; q[k++]=p[i++])
while(k > 1 && sgn(Cross(q[k-1]-q[k-2], p[i]-q[k-1])) <= 0) --k;
for(register int i=t-2, j=k; i>=0; q[k++]=p[i--])
while(k > j && sgn(Cross(q[k-1]-q[k-2], p[i]-q[k-1])) <= 0) --k;
q.resize(k-1);
return q;
}
Gym - 100941D
VJudge
给你n个嵌套的凸多边形,再给你m个点坐标,求m个点所在封闭区域的面积和。 (精度1e-6)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iomanip>
#include<vector>
#define llong long long
#define For(i,a,n) for(register llong i=a;i<=n;++i)
#define RF(i,a,n) for(register llong i=a;i>=n;--i)
#define maxn 100005
#pragma GCC optimize(2)
using namespace std;
const double eps = 1e-7;
inline void in(llong &x){
llong y=1; char c=getchar(); x=0;
while(c<'0'||c>'9'){
if(c=='-') y=-1;
c=getchar();
}
while(c<='9'&&c>='0') x=(x<<1)+(x<<3)+c-'0',c=getchar();
x*=y;
}
struct Point{
llong x, y;
Point(){}
Point(llong x, llong y):x(x),y(y){}
Point operator - (Point &b){
return Point(x-b.x, y-b.y);
}
bool operator < (Point p){
if(y!=p.y) return y<p.y;
return x<p.x;
}
};
struct node{
double mj;
int id;
bool operator < (const node &b)const{
return mj < b.mj;
}
}a[maxn];
llong n, pnum, m;
llong ans;
int flag[maxn];
vector<Point> poly[maxn];
inline llong sgn(llong d){
if(d<eps) return -1;
return d>eps;
}
inline llong Cross(Point A, Point B) { return A.x*B.y-A.y*B.x;}
inline llong PolygonArea(vector<Point> p){
llong n = p.size();
llong ans = 0;
for(llong i = 1; i < n-1; ++i)
ans += Cross(p[i]-p[0], p[i+1]-p[0]);
return ans;
}
inline bool isPointInPolygon(Point p,vector<Point> con)
{
int k = con.size();
if(k<3) return 0;
if(Cross(p-con[0],con[1]-con[0])>-eps) return 0;
if(Cross(p-con[0],con[k-1]-con[0])<eps) return 0;
int i=2,j=k-1;
int line=-1;
while(i<=j)
{
int mid=(i+j)>>1;
if(Cross(p-con[0],con[mid]-con[0])>-eps)
{
line=mid;
j=mid-1;
}
else i=mid+1;
}
if(line>0)
return Cross(p-con[line-1],con[line]-con[line-1])<-eps;
return 0;
}
inline vector<Point> ConvexHull(vector<Point> p, llong t){
if(t<=1) return p;
sort(p.begin(), p.end());
vector<Point> q(t*2);
llong k = 0;
for(register llong i=0; i<t; q[k++]=p[i++])
while(k>1&&sgn(Cross(q[k-1]-q[k-2], p[i]-q[k-1]))<=0) --k;
for(register llong i=t-2, j=k; i>=0; q[k++]=p[i--])
while(k>j&&sgn(Cross(q[k-1]-q[k-2], p[i]-q[k-1]))<=0) --k;
q.resize(k-1);
return q;
}
int main(){
in(n);
For(i,1,n){
in(pnum);
poly[i].resize(pnum);
For(j,0,pnum-1){
in(poly[i][j].x); in(poly[i][j].y);
}
poly[i] = ConvexHull(poly[i], pnum);
a[i].mj = PolygonArea(poly[i]);
a[i].id = i;
}
sort(a+1, a+n+1);
in(m);
while(m--){
Point t;
in(t.x); in(t.y);
int l = 1, r = n+1;
while(l<r){
int mid = (l+r)>>1;
if(mid == n+1) continue;
if(isPointInPolygon(t, poly[a[mid].id])){
r = mid;
}
else {
l = mid+1;
}
}
if(l != n+1 && !flag[l]) flag[l] = 1, ans+=a[l].mj-a[l-1].mj;
}
printf("%0.6f\n", ans/2.0);
return 0;
}