[sslOJ1213][计算几何]多边形面积(difficult)

题面


sslOJ \(Link\)

思路

首先题目讲明,这个是一个由\((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;
} 
posted @ 2022-01-20 15:06  unknown_future  阅读(30)  评论(0编辑  收藏  举报