题目:Art Gallery
题意:在一个建筑物里面要放置一个监控,使得能监控到建筑物里所有地方,问能放置监控的面积有多大。
简单的半平面交,直接套模板然后求面积即可,模板是参考《训练指南》的。
输入我是当它是顺时针(分析第一个样例。。。),好像我来回读了几遍题目都没get到点输入顺序的信息 = = ,但是如果没顺序感觉又确定不了建筑物。。。但至少按照顺时针是能AC的。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps = 1e-8;
const int N = 2001;
struct Point{
double x, y;
Point(){}
Point(double x, double y):x(x),y(y){}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B){
return Vector(A.x+B.x, A.y+B.y);
}
Vector operator - (Point A, Point B){
return Vector(A.x-B.x, A.y-B.y);
}
Vector operator * (Vector A, double a){
return Vector(A.x*a, A.y*a);
}
Vector operator / (Vector A, double a){
return Vector(A.x/a, A.y/a);
}
int dcmp(double x){
if(fabs(x)<eps) return 0;
return x<0?-1:1;
}
double Dot(Vector A, Vector B){
return A.x*B.x + A.y*B.y;
}
double Det(Vector A, Vector B){
return A.x*B.y - A.y*B.x;
}
struct Line{
Point P;
Vector v;
double ang;
Line(){}
Line(Point P, Vector v):P(P),v(v){
ang = atan2(v.y, v.x);
}
bool operator < (const Line &tmp)const{
return ang < tmp.ang;
};
};
bool OnLeft(Line L, Point p){
return Det(L.v, p-L.P) > 0;
}
Point GetIntersection(Line a, Line b){
Vector u = a.P-b.P;
double t = Det(b.v, u) / Det(a.v, b.v);
return a.P+a.v*t;
}
Point pt[N], poly[N];
Line L[N], Q[N];
int t, n;
int HalfPlane(){
sort(L, L+n);
int head, tail;
Q[head=tail=0] = L[0];
for(int i=1; i<n; i++){
while(head<tail && !OnLeft(L[i], pt[tail-1])) tail--;
while(head<tail && !OnLeft(L[i], pt[head])) head++;
Q[++tail] = L[i];
if(fabs(Det(Q[tail].v, Q[tail-1].v)) < eps){
tail--;
if(OnLeft(Q[tail], L[i].P)) Q[tail] = L[i];
}
if(head < tail) pt[tail-1] = GetIntersection(Q[tail-1], Q[tail]);
}
while(head < tail && !OnLeft(Q[head], pt[tail-1])) tail--;
if(tail - head <= 1) return 0;
pt[tail] = GetIntersection(Q[tail], Q[head]);
int m = 0;
for(int i=head; i<=tail; i++) poly[m++] = pt[i];
return m;
}
double Area(int m){
double S=0.0;
for(int i=1; i<m-1; i++){
S += Det(poly[i]-poly[0], poly[i+1]-poly[0]);
}
return fabs(S)*0.5;
}
int main(){
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%lf %lf", &pt[i].x, &pt[i].y);
}
pt[n] = pt[0];
for(int i=0; i<n; i++){
L[i] = Line(pt[i+1], pt[i]-pt[i+1]);
}
int m = HalfPlane();
printf("%.2lf\n", Area(m));
}
return 0;
}