#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\n" , ++ca);
if
(convexIntersection()) {
puts ( "Surveillance is possible." );
}
else
puts ( "Surveillance is impossible." );
puts ( "" );
}
return
0;
}
|