Art Gallery
64-bit integer IO format: %lld Java class name: Main
Input
Output
Sample Input
1 7 0 0 4 4 4 7 9 7 13 -1 8 -6 4 -4
Sample Output
80.00
Source
首先這些點是順時針的,那麼我讀入這些點之後就要逆置一下,
然後不能排序
第一個半平面交(O(n^2))
代碼:
//(O(n^2))
#include
#include
#include
#define maxn 10000
using namespace std;
typedef long long int LLI;
const double eps = 1e-18;
int sgn(double x) {
if(fabs(x) < eps)return 0;
if(x < 0)return -1;
else return 1;
}
struct Point {
double x,y;
Point() {}
Point(double _x,double _y) {
x = _x;
y = _y;
}
Point operator -(const Point &b)const {
return Point(x - b.x, y - b.y);
}
double operator ^(const Point &b)const {
return x*b.y - y*b.x;
}
double operator *(const Point &b)const {
return x*b.x + y*b.y;
}
};
//計算多邊形面積
double CalcArea(Point p[],int n) {
double res = 0;
for(int i = 0; i < n; i++)
res += (p[i]^p[(i+1)%n]);
return fabs(res/2);
}
//通過兩點,確定直線方程
void Get_equation(Point p1,Point p2,double &a,double &b,double &c) {
a = p2.y - p1.y;
b = p1.x - p2.x;
c = p2.x*p1.y - p1.x*p2.y;
}
//求交點
Point Intersection(Point p1,Point p2,double a,double b,double c) {
double u = fabs(a*p1.x + b*p1.y + c);
double v = fabs(a*p2.x + b*p2.y + c);
Point t;
t.x = (p1.x*v + p2.x*u)/(u+v);
t.y = (p1.y*v + p2.y*u)/(u+v);
return t;
}
Point tp[110];
void Cut(double a,double b,double c,Point p[],int &cnt) {
int tmp = 0;
for(int i = 1; i <= cnt; i++) {
//當前點在左側,逆時針的點
if(a*p[i].x + b*p[i].y + c < eps)tp[++tmp] = p[i];
else {
if(a*p[i-1].x + b*p[i-1].y + c < -eps)
tp[++tmp] = Intersection(p[i-1],p[i],a,b,c);
if(a*p[i+1].x + b*p[i+1].y + c < -eps)
tp[++tmp] = Intersection(p[i],p[i+1],a,b,c);
}
}
for(int i = 1; i <= tmp; i++)
p[i] = tp[i];
p[0] = p[tmp];
p[tmp+1] = p[1];
cnt = tmp;
}
const double INF = 100000.0;
Point p[110];
Point List[maxn];
int main() {
// freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t --) {
int n;
scanf("%d",&n);
for(int i = 0; i < n; i ++)
scanf("%lf%lf",&List[i].x,&List[i].y);
reverse(List,List + n);
p[1] = Point(-INF,-INF);
p[2] = Point(INF,-INF);
p[3] = Point(INF,INF);
p[4] = Point(-INF,INF);
p[0] = p[4];
p[5] = p[1];
int cnt = 4;
for(int i = 1; i <= n; i ++) {
double a,c,b;
a = List[i % n].y - List[i - 1].y;
b = -List[i % n].x + List[i - 1].x;
c = List[i % n].x * List[i - 1].y - List[i - 1].x * List[i % n].y;
Cut(a,b,c,p,cnt);
}
printf("%.2f\n",CalcArea(p,cnt));
}
return 0;
}