POJ1474 Video Surveillance(半平面交)

求多边形核的存在性,过了这题但是过不了另一题的,不知道是模板的问题还是什么,但是这个模板还是可以过绝大部分的题的。。。

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;

#define maxn 2500
#define eps 1e-7

int n;

int dcmp(double x){
	return x<-eps ? -1 : x>eps;
}

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);
	}
	Point operator - (const Point &b) const{
		return Point(x - b.x, y - b.y);
	}
	Point operator *(double d) const{
		return Point(x*d, y*d);
	}
	Point operator /(double d) const{
		return Point(x / d, y / d);
	}
	double det(const Point &b) const{
		return x*b.y - y*b.x;
	}
	double dot(const Point &b) const{
		return x*b.x + y*b.y;
	}
	Point rot90(){
		return Point(-y, x);
	}
	Point norm(){
		double len = sqrt(this->dot(*this));
		return Point(x, y) / len;
	}
	void read(){
		scanf("%lf%lf", &x, &y);
	}
};

#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
#define crossOp(p1,p2,p3) (dcmp(cross(p1,p2,p3)))

Point isSS(Point p1, Point p2, Point q1, Point q2){
	double a1 = cross(q1, q2, p1), a2 = -cross(q1, q2, p2);
	return (p1*a2 + p2*a1) / (a1 + a2);
}

struct Border
{
	Point p1, p2;
	double alpha;
	void setAlpha(){
		alpha = atan2(p2.y - p1.y, p2.x - p1.x);
	}
};

bool operator < (const Border &a, const Border &b) {
	int c = dcmp(a.alpha - b.alpha);
	if (c != 0) {
		return c > 0;
	}
	else {
		return crossOp(b.p1, b.p2, a.p1) > 0;
	}
}

bool operator == (const Border &a, const Border &b){
	return dcmp(a.alpha - b.alpha) == 0;
}


Point isBorder(const Border &a, const Border &b){
	return isSS(a.p1, a.p2, b.p1, b.p2);
}

Border border[maxn];
Border que[maxn];
int qh, qt;
// check函数判断的是新加的半平面和由a,b两个半平面产生的交点的方向,若在半平面的左侧返回True
bool check(const Border &a, const Border &b, const Border &me){
	Point is = isBorder(a, b);
	return crossOp(me.p1, me.p2, is) >= 0;
}

bool isParellel(const Border &a, const Border &b){
	return dcmp((a.p2 - a.p1).det(b.p2 - b.p1)) == 0;
}

bool convexIntersection()
{
	qh = qt = 0;
	sort(border, border + n);
	n = unique(border, border + n) - border;
	for (int i = 0; i < n; i++){
		Border cur = border[i];
		while (qh + 1 < qt&&!check(que[qt - 2], que[qt - 1], cur)) --qt;
		while (qh + 1 < qt&&!check(que[qh], que[qh + 1], cur)) ++qh;
		que[qt++] = cur;
	}
	while (qh + 1 < qt&&!check(que[qt - 2], que[qt - 1], que[qh])) --qt;
	while (qh + 1 < qt&&!check(que[qh], que[qh + 1], que[qt - 1])) ++qh;
	return qt - qh > 2;
}

Point ps[maxn];

int main()
{
	int ca = 0;
	while (cin >> n&&n)
	{
		for (int i = 0; i < n; i++){
			ps[i].read();
		}
		ps[n] = ps[0];
		for (int i = 0; i < n; i++){
			border[i].p1 = ps[i + 1];
			border[i].p2 = ps[i];
			border[i].setAlpha();
		}
		printf("Floor #%d
", ++ca);
		if (convexIntersection()) {
			puts("Surveillance is possible.");
		}
		else puts("Surveillance is impossible.");
		puts("");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/chanme/p/3710586.html