[sslOJ1213][计算几何]多边形面积(difficult)
题面
思路
首先题目讲明,这个是一个由\((1, 2), (2, 3)......(n - 1, n), (n, 1)\)这些边构成的点。
于是利用叉积算出这个多边形的面积。
但是题目里说过,这个多边形可能是不合法的。
有两种情况:
1)点的数量小于等于二
2)非相邻的边相交了
所以再枚举每两条非相邻的边是否相交就可以了
Code
#include <cmath>
#include <stdio.h>
#include <iostream>
#define N 1005
using namespace std;
int n;
double ans;
double x[N], y[N];
struct node
{
double x, y;
}p1, p2, p3, p4;
double hd (int a, int b)
{
double m = x[a] * y[b] - x[b] * y[a];
//if (m < 0) m *= -1;
return m *= 0.5;
}
double m (node p1, node p2, node p3)
{
return (p1.x - p3.x) * (p2.y - p3.y) - (p1.y - p3.y) * (p2.x - p3.x);
}
int online (node p1, node p2, node p3)
{
if (p3.x >= min (p1.x, p2.x) && p3.x <= max (p1.x, p2.x) && p3.y >= min (p1.y, p2.y) && p3.y <= max (p1.y, p2.y)) return 1;
return 0;
}
int check (node p1, node p2, node p3, node p4)
{
if (m (p3, p4, p1) * m (p3, p4, p2) < 0 && m (p1, p2, p3) * m (p1, p2, p4) < 0)
return 1;
if (m (p3, p4, p1) == 0 && online (p3, p4, p1))
return 1;
if (m (p3, p4, p2) == 0 && online (p3, p4, p2))
return 1;
if (m (p1, p2, p3) == 0 && online (p1, p2, p3))
return 1;
if (m (p1, p2, p4) == 0 && online (p1, p2, p4))
return 1;
return 0;
}
int main ()
{
scanf ("%d", &n);
for (int i = 1; i <= n; ++ i)
{
scanf ("%lf%lf", &x[i], &y[i]);
if (i > 1) ans += hd (i - 1, i);
}
ans += hd (n, 1);
for (int i = 1; i <= n; ++ i)
{
for (int j = i + 2; j <= n; ++ j)
{
int it = i + 1, jt = j + 1;
if (jt > n) jt = 1;
if (jt == i) continue; // n 和 1 的情况
p1.x = x[i], p1.y = y[i];
p2.x = x[it], p2.y = y[it];
p3.x = x[j], p3.y = y[j];
p4.x = x[jt], p4.y = y[jt];
if (check (p1, p2, p3, p4))
{
printf ("Impossible");
return 0;
}
}
}
if (ans < 0) ans *= -1;
if (n < 3 ) printf ("Impossible");
else printf ("%.2lf", ans);
return 0;
}