Problem:
Problem B:
How I Mathematician Wonder What You Are!
After counting so many stars in the sky in his childhood, Isaac, now an astronomer and a
mathematician, uses a big astronomical telescope and lets his image processing program count
stars. The hardest part of the program is to judge if a shining object in the sky is really a star.
As a mathematician, the only way he knows is to apply a mathematical definition of
stars
.
The mathematical defiition of a star shape is as follows: A planar shape
F
is
star-shaped
if and
only if there is a point C ∈
F
such that, for any point P ∈
F
, the line segment CP is contained
in
F
. Such a point C is called a center of
F
. To get accustomed to the definition, let's see some
examples below.
Figure 2: Star shapes (the first row) and non-star shapes (the second row)
The firrst two are what you would normally call stars. According to the above definition, however,
all shapes in the first row are star-shaped. The two in the second row are not. For each star
shape, a center is indicated with a dot. Note that a star shape in general has infinitely many
centers. For example, for the third quadrangular shape, all points in it are centers.
Your job is to write a program that tells whether a given polygonal shape is star-shaped or not.
Input
The input is a sequence of datasets followed by a line containing a single zero. Each dataset
specifies a polygon, and is formatted as follows.
n
x
1
y
1
x
2
y
2
...
x
n
y
n
The first line is the number of vertices,
n
, which satisfies 4 ≤
n
≤ 50. Subsequent
n
lines are the
x
- and
y
-coordinates of the
n
vertices. They are integers and satisfy 0 ≤
x
i
≤ 10000 and 0 ≤
y
i
≤ 10000 (
i
= 1, ...,
n
). Line segments (
x
i
,
y
i
)-(
x
i
+1
,
y
i
+1
) (
i
= 1, ...,
n
- 1) and the line segment (
x
n
,
y
n
)-(
x
1
,
y
1
) form the border of the polygon in the counterclockwise order. That is, these line segments see the inside of the polygon in the left of their directions.
You may assume that the polygon is
simple
, that is, its border never crosses or touches itself.
You may also assume that no three edges of the polygon meet at a single point even when they
are infinitely extended.
Output
For each dataset, output "1" if the polygon is star-shaped and "0" otherwise. Each number must be in a separate line and the line should not contain any other characters.
Sample Input
6
66 13
96 61
76 98
13 94
4 0
45 68
8
27 21
55 14
93 12
56 95
15 48
38 46
51 65
64 31
0
Output for the Sample Input
1
0

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

typedef double P_type; //座標(integer or real)
typedef double G_real; //実数の戻り値(float or double or long double)
typedef complex<P_type> P;
const G_real P_eps = 1e-8; //整数の時はゼロ

namespace std{
  template<class T> bool operator<(const complex<T> &a, const complex<T> &b){
    return abs(a.real() - b.real()) < P_eps ? a.imag() + P_eps < b.imag() : a.real() + P_eps < b.real();
  }
};

P rotate(P p, double theta){
  return p * P(cos(theta), sin(theta));
}

//内積
P_type dot(P a, P b) {
  return (a * conj(b)).real();
}

//外積
P_type cross(P a, P b) {
  return (conj(a) * b).imag();
}

//反時計回り
int ccw(P a, P b, P c){
  if(cross(b-a, c-a) > P_eps) return 1; //COUNTER_CLOCKWISE(center:a)
  if(cross(b-a, c-a) < -P_eps) return -1; //CLOCKWISE(center:a)
  if(dot(b-a, c-a) < -P_eps) return -2; //c -> a -> b
  if(dot(a-b, c-b) < -P_eps) return 2; //a -> b -> c
  return 0; //a -> c -> b
}

/* 線分abと点cの距離 */
G_real distanceSP(P a, P b, P c) {
  if ( dot(b-a, c-a) < P_eps ) return abs(c-a);
  if ( dot(a-b, c-b) < P_eps ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 直線abと点cの距離 */
G_real distanceLP(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 円の点包含判定 */
bool isContainedCP(P c, P_type r, P p){
  return abs(c-p) < r - P_eps; //円周上を含まない
  //return abs(c-p) <= r + P_eps; //円周上を含む
}

/* 直線交差判定 */
bool isIntersectedLL(P a1, P a2, P b1, P b2){
  return abs(cross(a1-a2, b1-b2)) > P_eps;
}

/* 線分交差判定 */
bool isIntersectedSS(P a1, P a2, P b1, P b2){

  //線分a と 直線b
  int a = ccw(b1, b2, a1);
  int b = ccw(b1, b2, a2);

  //線分b と 直線a
  int c = ccw(a1, a2, b1);
  int d = ccw(a1, a2, b2);

  return a * b <= 0 && c * d < 0; // T字を除く時は (** < 0)
}

/* 直線A線分B交差判定 */
bool isIntersectedLS(P a1, P a2, P b1, P b2){
  int a = ccw(a1, a2, b1);
  int b = ccw(a1, a2, b2);

  // 直線上のとき a or b = 0 or -2 or 2
  return (a % 2) * (b % 2) <= 0; // T字を除く時は (** < 0)
}

/* 円交差判定 */
bool isIntersectedCC(P c1, G_real r1, P c2, P_type r2){
  G_real dist = abs(c1 - c2);

  return abs(r1 - r2) <= dist + P_eps && dist - P_eps <= r1 + r2; //外接内接を含む
  //return abs(r1 - r2) < dist - P_eps && dist + P_eps < r1 + r2; //外接内接を除く
}

/* 円直線交差判定 */
bool isIntersectedCL(P c, G_real r, P a1, P a2){
  return distanceLP(a1, a2, c) <= r + P_eps; //接する場合を含まない場合 < r - P_eps
}

/* 円線分交差判定 */
bool isIntersectedCS(P c, P_type r, P a1, P a2){
  return (!isContainedCP(c, r, a1) || !isContainedCP(c, r, a2)) &&
    distanceLP(a1, a2, c) <= r + P_eps; //接する場合を含まない場合 < r - P_eps
}

/* 直線/線分交点 */
P getCrosspointLL(P a1, P a2, P b1, P b2) {
  //assert(isIntersectedLL(a1, a2, b1, b2));
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1) / cross(b, a);
}

P getCrosspointSS(P a1, P a2, P b1, P b2){
  //assert(isIntersectedSS(a1, a2, b1, b2));
  return getCrosspointLL(a1, a2, b1, b2);
}

/* 円交点 */
pair<P,P> getCrosspointCC(P c1, P_type r1, P c2, P_type r2){
  //assert(isIntersectedCC(c1, r1, c2, r2));

  P_type dist = abs(c1 - c2);
  P_type a = acos((r1*r1 + dist*dist - r2*r2) / (2 * r1 * dist));
  return {c1 + polar(r1, arg(c2 - c1) + a), c1 + polar(r1, arg(c2 - c1) - a)};
}

/* 円直線交点 */
vector<P> getCrosspointCL(P c, P_type r, P a1, P a2){
  if(!isIntersectedCL(c, r, a1, a2)) return {};

  P base1 = a2 - a1;
  P proj = a1 + base1 * dot(c - a1, base1) / norm(base1); //射影
  P e = (a2 - a1) / abs(a2 - a1);
  P base2 = sqrt(r*r - norm(proj - c));
  return {proj - e*base2, proj + e*base2};
}

/* 円線分交点 */
vector<P> getCrosspointCS(P c, P_type r, P a1, P a2){
  if(!isIntersectedCS(c, r, a1, a2)) return {};

  vector<P> res;
  for(P p : getCrosspointCL(c, r, a1, a2))
    if(dot(a1-p, a2-p) <= P_eps) res.push_back(p);
  return res;
}

/* 多角形-点包含 */
bool isContainedPolyP(vector<P> &g, P p){
  int n = g.size();
  bool f = false;
  for(int i=0; i<n; i++){
    P a = g[i] - p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) < P_eps && dot(a,b) < P_eps) return true; //辺上
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() < P_eps && P_eps < b.imag() && cross(a,b) > P_eps) f = !f;
  }
  return f; //内部 or 外部
}

bool isContainedPolyS(vector<P> &g, P a, P b) {

  if(!isContainedPolyP(g, a)) return false;
  if(!isContainedPolyP(g, b)) return false;

  P d = b - a;

  P a2 = a + d * (P_eps * 1e2);
  P b2 = b - d * (P_eps * 1e2);

  if(!isContainedPolyP(g, a2)) return false;
  if(!isContainedPolyP(g, b2)) return false;

  for(int i=0; i<g.size(); i++)
    if(isIntersectedSS(a, b, g[i], g[(i+1)%g.size()]))
      return false;

  return true;
}


bool solve() {
  int N;
  P p[51];
  vector<P> poly;

  scanf("%d", &N);

  if (N == 0) return false;

  for (int i=0; i<N; i++) {
    int x, y;

    scanf("%d%d", &x, &y);

    p[i] = P(x, y);
    poly.push_back(p[i]);
  }
  p[N] = p[0];

  for(int i=0; i<N; i++) {
    for(int j=i+1; j<N; j++) {
      if (isIntersectedLL(p[i], p[i+1], p[j], p[j+1])) {
        P g = getCrosspointLL(p[i], p[i+1], p[j], p[j+1]);

        if (!isContainedPolyP(poly, g)) continue;

        bool ok = true;
        for (int i=0; i<N && ok; i++) {
          ok &= isContainedPolyS(poly, g, p[i]);
        }

        if (ok) {
          puts("1");
          return true;
        }
      }
    }
  }

  puts("0");
  return true;
}


int main(){

  while(solve());

  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3112
final_rank: 9

code_snippet: #include<iomanip>
#include<limits>
#include<thread>
#include<utility>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<numeric>
#include<cassert>
#include<random>
#include<chrono>
#include<unordered_set>
#include<unordered_map>
#include<fstream>
#include<list>
#include<functional>
#include<bitset>
#include<complex>
#include<tuple>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
const ll MOD=1000000007;


template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

namespace Geometry{
    typedef long double D;
    typedef complex<long double> P;
    typedef pair<P,D> C;
    
    const D EPS=1e-9;
    const D PI=asin(1)*2;
    const D INF=1e18;
    
    const static bool comp(const P &p1,const P &p2){return p1.real()==p2.real()?p1.imag()<p2.imag():p1.real()<p2.real();}
    
    D dot(P p1,P p2){return p1.real()*p2.real()+p1.imag()*p2.imag();}
    
    D cross(P p1,P p2){return p1.real()*p2.imag()-p1.imag()*p2.real();}
    
    P project(P vec,P x){return vec*(x/vec).real();}
    
    P project(P p1,P p2,P x){return p1+project(p2-p1,x-p1);}
    
    P reflect(P vec,P x){return vec*conj(x/vec);}
    
    P reflect(P p1,P p2,P x){return p1+reflect(p2-p1,x-p1);}
    
    bool intersectSL(P p1,P p2,P vec){vec/=abs(vec); p1/=vec; p2/=vec; return (p1.imag()<EPS && p2.imag()>-EPS) || (p1.imag()>-EPS && p2.imag()<EPS);}
    
    bool intersectSL(P p1,P p2,P p3,P p4){return intersectSL(p1-p4,p2-p4,p3-p4);}
    
    bool intersectSS(P p1,P p2,P p3,P p4){return (dot(p2-p1,p3-p1)<-EPS && dot(p2-p1,p4-p1)<-EPS) || (dot(p1-p2,p3-p2)<-EPS && dot(p1-p2,p4-p2)<-EPS)?false:intersectSL(p1,p2,p3,p4) && intersectSL(p3,p4,p1,p2);}
    
    D distLP(P vec,P x){return abs((x/vec).imag())*abs(vec);}
    
    D distLP(P p1,P p2,P x){return distLP(p2-p1,x-p1);}
    
    D distSP(P p1,P p2,P x){return dot(p2-p1,x-p1)<-EPS?abs(x-p1):dot(p1-p2,x-p2)<-EPS?abs(x-p2):distLP(p1,p2,x);}
    
    D distSS(P p1,P p2,P p3,P p4){return intersectSS(p1,p2,p3,p4)?0.0:min(min(distSP(p1,p2,p3),distSP(p1,p2,p4)),min(distSP(p3,p4,p1),distSP(p3,p4,p2)));}
    
    P crosspointLL(P p1,P p2,P vec){return abs(cross(p2-p1,vec))<EPS?vec:vec*cross(p2-p1,p2)/cross(p2-p1,vec);}
    
    P crosspointLL(P p1,P p2,P p3,P p4){return p4+crosspointLL(p1-p4,p2-p4,p3-p4);}
    
    P crosspointSS(P p1,P p2,P p3,P p4){return distSP(p1,p2,p3)<EPS?p3:distSP(p1,p2,p4)<EPS?p4:crosspointLL(p1,p2,p3,p4);}
    
    bool intersectShL(P p1,P p2,P vec){vec/=abs(vec); return intersectSL(p1,p2,vec) && crosspointLL(p1/vec,p2/vec,vec/vec).real()>-EPS;}
    
    bool intersectShL(P p1,P p2,P p3,P p4){return intersectShL(p1-p3,p2-p3,p4-p3);}
    
    //1::in,0::on edge,-1::out
    int contain(const vector<P> &poly,const P &p){
        vector<P> A={{65537,96847},{-24061,6701},{56369,-86509},{-93763,-78049},{56957,10007}};
        vector<bool> cnt(5,false);
        for(int i=1;i<=poly.size();i++){
            if(distSP(poly[i-1],poly[i%poly.size()],p)<EPS){return 0;}
            for(int j=0;j<5;j++){
                if(intersectShL(poly[i-1],poly[i%poly.size()],p,p+A[j])){cnt[j]=!cnt[j];}
            }
        }
        int in=0;
        for(int j=0;j<5;j++){if(cnt[j]){in++;}}
        return in>=3?1:-1;
    }
    
    vector<P> convexcut(const vector<P> &poly,P p1,P p2){
        vector<P> ret;
        for(int i=1;i<=poly.size();i++){
            if(cross(p2-p1,poly[i-1]-p1)>-EPS){ret.push_back(poly[i-1]);}
            if(intersectSL(poly[i-1],poly[i%poly.size()],p1,p2) && distLP(p1,p2,poly[i-1])>EPS && distLP(p1,p2,poly[i%poly.size()])>EPS){ret.push_back(crosspointLL(poly[i-1],poly[i%poly.size()],p1,p2));}
        }
        return ret;
    }
    
    D area(const vector<P> &poly){
        D ans=0;
        for(int i=2;i<poly.size();i++){ans+=cross(poly[i-1]-poly[0],poly[i]-poly[0]);}
        return abs(ans)/2;
    }
    
    vector<P> convexhull(vector<P> pts){
        vector<P> ret;
        sort(pts.begin(),pts.end(),comp);
        for(auto &I:pts){
            if(!ret.empty() && I==ret.back()){continue;}
            while(ret.size()>=2 && cross(ret.back()-ret[ret.size()-2],I-ret.back())<-EPS){ret.pop_back();}
            ret.push_back(I);
        }
        reverse(pts.begin(),pts.end());
        for(auto &I:pts){
            if(!ret.empty() && I==ret.back()){continue;}
            while(ret.size()>=2 && cross(ret.back()-ret[ret.size()-2],I-ret.back())<-EPS){ret.pop_back();}
            ret.push_back(I);
        }
        if(ret[0]==ret.back()){ret.pop_back();}
        return ret;
    }
    
    //4::seperate,3::circumscribe,2::intersect,1::inscribe,0::contain,-1::same
    int intersectCC(C c1,C c2){
        D d=abs(c1.F-c2.F),r=c1.S+c2.S,dif=abs(c2.S-c1.S);
        if(d<EPS && dif<EPS){return -1;}
        if(d-r>EPS){return 4;}
        if(d-r>-EPS){return 3;}
        if(d-dif>EPS){return 2;}
        if(d-dif>-EPS){return 1;}
        return 0;
    }
    
    vector<P> crosspointLC(P p1,P p2,C c){
        vector<P> ret;
        P pr=project(p1,p2,c.F);
        D d=distLP(p1,p2,c.F);
        if(d-c.S>EPS){return ret;}
        if(d-c.S>-EPS){ret.push_back(pr); return ret;}
        P vec=p2-p1; vec*=sqrt(c.S*c.S-d*d)/abs(vec);
        ret.push_back(pr-vec);
        ret.push_back(pr+vec);
        return ret;
    }
    
    vector<P> crosspointSC(P p1,P p2,C c){
        vector<P> ret;
        for(auto &I:crosspointLC(p1,p2,c)){if(distSP(p1,p2,I)<EPS){ret.push_back(I);}}
        return ret;
    }
    
    vector<P> crosspointCC(C c1,C c2){
        vector<P> ret;
        P vec=c2.F-c1.F;
        D base=(c1.S*c1.S+norm(vec)-c2.S*c2.S)/(2*abs(vec));
        D h=sqrt(c1.S*c1.S-base*base);
        vec/=abs(vec);
        ret.push_back(c1.F+vec*P(base,-h));
        ret.push_back(c1.F+vec*P(base,h));
        return ret;
    }
    
    vector<P> tangentCP(C c,P p){return crosspointCC(c,C(p,sqrt(norm(c.F-p)-c.S*c.S)));}
    
    vector<pair<P,P>> tangentCC(C c1,C c2){
        vector<pair<P,P>> ret;
        P d=c2.F-c1.F;
        for(D i:{-1,1}){
            D r=c1.S+c2.S*i;
            if(intersectCC(c1,c2)>i+1){
                for(P s:{-1i,1i}){
                    P p=r+s*sqrt(norm(d)-norm(r));
                    ret.push_back({c1.F+d*c1.S/norm(d)*p,c2.F-d*i*c2.S/norm(d)*p});
                }
            }
        }
        return ret;
    }
    
    D area(const vector<P> &poly,C c){
        D ret=0;
        for(int i=0;i<poly.size();i++){
            P a=poly[i]-c.F,b=poly[(i+1)%poly.size()]-c.F;
            if(abs(a)<c.S+EPS && abs(b)<c.S+EPS){ret+=cross(a,b);}
            else{
                vector<P> A=crosspointSC(a,b,{0,c.S});
                if(A.empty()){ret+=c.S*c.S*arg(b/a);}
                else{
                    ret+=(abs(a)<c.S?cross(a,A[0]):c.S*c.S*arg(A[0]/a));
                    ret+=(abs(b)<c.S?cross(A.back(),b):c.S*c.S*arg(b/A.back()));
                    ret+=cross(A[0],A.back());
                }
            }
        }
        return abs(ret)/2;
    }
    
    //反時計回り
    D diameter(const vector<P> &poly){
        D ret=0;
        ll l=0,r=0,n=poly.size();
        if(n==2){return abs(poly[0]-poly[1]);}
        for(int i=0;i<n;i++){
            if(comp(poly[l],poly[i])){l=i;}
            if(comp(poly[i],poly[r])){r=i;}
        }
        ll sl=r,sr=l;
        while(sl!=l || sr!=r){
            ret=max(ret,abs(poly[r]-poly[l]));
            if(cross(poly[(l+1)%n]-poly[l],poly[(r+1)%n]-poly[r])<0){(++l)%=n;}
            else{(++r)%=n;}
        }
        return ret;
    }
    
    D closestpair(vector<P> pt){
        sort(pt.begin(),pt.end(),comp);
        D ret=INF;
        for(ll i=1;i<pt.size();i<<=1){
            for(ll j=0;i+j<pt.size();j+=i*2){
                ll m=i+j;
                vector<P> R;
                D l=-INF,r=INF;
                for(ll k=j;k<m;k++){l=max(l,pt[k].real());}
                for(ll k=0;m+k<pt.size() && k<i;k++){r=min(r,pt[m+k].real());}
                for(ll k=0;m+k<pt.size() && k<i;k++){if(pt[m+k].real()-l<ret){R.push_back(pt[m+k]);}}
                ll idx=0;
                for(ll k=j;k<m;k++){
                    if(r-pt[k].real()>ret){continue;}
                    while(idx<R.size() && pt[k].imag()-R[idx].imag()>ret){idx++;}
                    for(ll n=idx;n<R.size() && R[n].imag()-pt[k].imag()<ret;n++){ret=min(ret,abs(R[n]-pt[k]));}
                }
                inplace_merge(pt.begin()+j,pt.begin()+m,j+i*2<pt.size()?pt.begin()+j+2*i:pt.end(),[](const P &a,const P &b){return a.imag()==b.imag()?a.real()<b.real():a.imag()<b.imag();});
            }
        }
        return ret;
    }
    
    istream & operator >> (istream &i,P &p){D x,y; i>>x>>y; p={x,y}; return i;}
    istream & operator >> (istream &i,C &p){D x,y; i>>x>>y>>p.S; p.F={x,y}; return i;}
};

using namespace Geometry;



int main(){
    ll n;
    while(cin>>n,n){
        vector<P> A(n);
        cin>>A;
        vector<P> B=convexhull(A);
        vector<P> C=B;
        for(int i=1;i<=n;i++){
            if(contain(B,A[i-1])==1 || contain(B,A[i%n])==1){
                C=convexcut(C,A[i-1],A[i%n]);
            }
        }
        cout<<(C.empty()?0:1)<<endl;
    }
    
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3228
final_rank: 8

code_snippet: #include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;

using ld = double;
using Point =  complex<ld>;
const ld eps = 1e-9;
const ld pi = acos(-1.0);

bool eq(ld a, ld b) {
	return (abs(a - b) < eps);
}

bool cmp(Point x,Point y){
	if(eq(x.real(),y.real()))return x.imag()<y.imag();
	return x.real()<y.real();
}

bool eqq(Point x,Point y){
	return eq(x.real(),y.real())&&eq(x.imag(),y.imag());
}
//内積
ld dot(Point a, Point b) {
	return real(conj(a)*b);
}
//外積
ld cross(Point a, Point b) {
	return imag(conj(a)*b);
}


//線分
//直線にするなら十分通い２点を端点とすればよい
class Line {
public:
	Point a, b;
};
//円
class Circle {
public:
	Point p;
	ld r;
};
//3点の位置関係
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//a,b,cが反時計回り
	if (cross(b, c) < -eps)return -1;//a,b,cが時計回り
	if (dot(b, c) < 0)return 2;//c,a,bの順に一直線
	if (norm(b) < norm(c))return -2;//a,b,cの順に一直線
	return 0;//a,c,bの順に一直線
}
//2直線の交差判定
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
//直線と線分の交差判定
bool isis_ls(Line l, Line s) {
	return (cross(l.b - l.a, s.a - l.a)*cross(l.b - l.a, s.b - l.a) < eps);
}
//点が直線上に存在するか
bool isis_lp(Line l, Point p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}
//点が線分上に存在するか
bool isis_sp(Line s, Point p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
//線分と線分の交差判定
bool isis_ss(Line s, Line t) {
	if (isis_sp(t, s.a) || isis_sp(t, s.b))return false;
	if (isis_sp(s, t.a) || isis_sp(s, t.b) )return false;
	return(cross(s.b - s.a, t.a - s.a)*cross(s.b - s.a, t.b - s.a) < -eps && cross(t.b - t.a, s.a - t.a)*cross(t.b - t.a, s.b - t.a) < -eps);
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}

Point cont(Line l, Point p){
	return 2.0*proj(l,p) - p;
}
//直線と直線の交点
//平行な２直線に対しては使うな！！！！
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
//直線と点の距離
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}
//直線と直線の距離
ld dist_ll(Line l, Line m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}
//線分と直線の距離
ld dist_ls(Line l, Line s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}
//線分と点の距離
ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
//線分と線分の距離
ld dist_ss(Line s, Line t) {
	if (isis_ss(s, t))return 0;
	return min({ dist_sp(s,t.a),dist_sp(s,t.b),dist_sp(t,s.a),dist_sp(t,s.b) });
}

bool included(vector<Point>& pol,Point p){
    double sum = 0;
    int n=pol.size();
    rep(i,n){
        Line l ={pol[i],pol[(i+1)%n]};
        if(isis_sp(l,p))return true;
        sum+=arg((pol[(i+1)%n]-p)/(pol[i]-p));
    }
    return abs(sum)>1;
}

void solve(int n){
    vector<Point> p(n);
    rep(i,n){
        int x,y;
        cin>>x>>y;
        p[i]=Point(x,y);
    }
    rep(i,n)rep(j,i){
        Line l1 = {p[i],p[(i+1)%n]};
        Line l2 = {p[j],p[(j+1)%n]};
        if(cross(l1.a-l1.b,l2.a-l2.b)<eps)continue;
        Point cr = is_ll(l1,l2);
        if(!included(p,cr))continue;
        bool can=true;
        rep(k,n){
            Line sg = {cr,p[k]};
            Point mid = (cr+p[k])*.5;
            if(!included(p,mid))can=false;
            rep(l,n){
                if(isis_ss(sg,{p[l],p[(l+1)%n]}))can = false;
            }
        }
        if(can){
            cout<<1<<endl;
            return;
        }
    }
    cout<<0<<endl;
    return;
}

int main(){
   int n;
   while(cin>>n,n)solve(n);
    return 0;
}
accuracy: 1
time_ms: 1060
memory_kb: 3244
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef complex<double> P;
typedef pair< P , P > L;
typedef pair< P , P > S;
typedef vector<P> vecP;
 
double eps = 1e-8;
 
bool eq(double a,double b){
  return -eps < a-b && a-b < eps;  
}
 
double cross(P a,P b){
  return imag( b*conj(a) );
}
 
double dot(P a,P b){
  return real( b*conj(a) );
}
 
bool isParallel(L a,L b){
  a.first -= a.second;
  b.first -= b.second;
  return eq(cross( a.first,b.first ),0);
}
 
P getCrossLL(L l0,L l1){
  P a=l0.first, b=l0.second;
  P c=l1.first, d=l1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}
 
int N;
P t[50];
L lines[1250];
P u[1250*1250];
 
int main(){
  while(1){
    scanf("%d",&N);
    if(N==0)break;
    for(int i=0;i<N;i++){
      int x,y;
      scanf("%d %d",&x,&y);
      t[i]=P(x,y);
    }
     
    int cc=0;    
    for(int i=0;i<N;i++)
      for(int j=0;j<i;j++)
        lines[cc++]=L(t[i],t[j]);
 
    int uc=0;
    for(int i=0;i<cc;i++)
      for(int j=0;j<i;j++)
        if( !isParallel(lines[i],lines[j]) )
          u[uc++]=getCrossLL(lines[i],lines[j]);
 
    int ans=0;
    for(int i=0;i<uc;i++){
      bool flg=true;
      P cen=u[i];
      for(int j=0;j<N;j++){
        P a=t[j];
        P b=t[ (j+1==N?0:j+1) ];
         
        if( cross(a-cen,b-cen) < -eps ){
          flg=false;
          break;
        }
         
      }
       
      if(flg){
        ans=1;
        break;
      }
    }
 
    printf("%d\n",ans);
  }
   
  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 27656
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef complex<double> P;
typedef pair< P , P > L;
typedef pair< P , P > S;
typedef vector<P> vecP;

double eps = 1e-8;

bool eq(double a,double b){
  return -eps < a-b && a-b < eps;  
}

double cross(P a,P b){
  return imag( b*conj(a) );
}

double dot(P a,P b){
  return real( b*conj(a) );
}

bool isParallel(L a,L b){
  a.first -= a.second;
  b.first -= b.second;
  return eq(cross( a.first,b.first ),0);
}

P getCrossLL(L l0,L l1){
  P a=l0.first, b=l0.second;
  P c=l1.first, d=l1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

int N;
P t[50];
L lines[1250];
P u[1250*1250];

int main(){
  while(1){
    scanf("%d",&N);
    if(N==0)break;
    for(int i=0;i<N;i++){
      int x,y;
      scanf("%d %d",&x,&y);
      t[i]=P(x,y);
    }
    
    int cc=0;    
    for(int i=0;i<N;i++)
      for(int j=0;j<i;j++)
        lines[cc++]=L(t[i],t[j]);

    int uc=0;
    for(int i=0;i<cc;i++)
      for(int j=0;j<i;j++)
        if( !isParallel(lines[i],lines[j]) )
          u[uc++]=getCrossLL(lines[i],lines[j]);

    int ans=0;
    for(int i=0;i<uc;i++){
      bool flg=true;
      P cen=u[i];
      for(int j=0;j<N;j++){
        P a=t[j];
        P b=t[ (j+1==N?0:j+1) ];
        
        if( cross(a-cen,b-cen) < -eps ){
          flg=false;
          break;
        }
        
      }
      
      if(flg){
        ans=1;
        break;
      }
    }

    printf("%d\n",ans);
  }
  
  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 27560
final_rank: 12

code_snippet: #include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e+10;
const double PI = acos(-1);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
inline double ABS(double a){return max(a,-a);}
struct Pt {
	double x, y;
	Pt() {}
	Pt(double x, double y) : x(x), y(y) {}
	Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
	Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
	Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
	Pt operator-() const { return Pt(-x, -y); }
	Pt operator*(const double &k) const { return Pt(x * k, y * k); }
	Pt operator/(const double &k) const { return Pt(x / k, y / k); }
	double ABS() const { return sqrt(x * x + y * y); }
	double abs2() const { return x * x + y * y; }
	double arg() const { return atan2(y, x); }
	double dot(const Pt &a) const { return x * a.x + y * a.y; }
	double det(const Pt &a) const { return x * a.y - y * a.x; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }
int iSP(Pt a, Pt b, Pt c) {
	int s = sig((b - a).det(c - a));
	if (s) return s;
	if (sig((b - a).dot(c - a)) < 0) return -2; // c-a-b
	if (sig((a - b).dot(c - b)) < 0) return +2; // a-b-c
	return 0;
}
int iLL(Pt a, Pt b, Pt c, Pt d) {
	if (sig((b - a).det(d - c))) return 1; // intersect
	if (sig((b - a).det(c - a))) return 0; // parallel
	return -1; // correspond
}
Pt pLL(Pt a, Pt b, Pt c, Pt d) {
	b = b - a; d = d - c; return a + b * (c - a).det(d) / b.det(d);
}
Pt p[60];
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++){
			double x,y;scanf("%lf%lf",&x,&y);
			p[i]=Pt(x,y);
		}p[a]=p[0];
		vector<Pt>v;
		for(int i=0;i<a;i++)for(int j=i+1;j<a;j++)for(int k=0;k<a;k++)for(int l=k+1;l<a;l++){
			if(iLL(p[i],p[j],p[k],p[l])==1)v.push_back(pLL(p[i],p[j],p[k],p[l]));
		}
		int ret=0;
		for(int i=0;i<v.size();i++){
			bool ok=true;
			for(int j=0;j<a;j++){
				if(iSP(p[j],v[i],p[j+1])==1)ok=false;
			}
			if(ok)ret=1;
		}
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 3620
memory_kb: 51932
final_rank: 15

code_snippet: //31
#include<iostream>
#include<complex>
#include<cmath>

using namespace std;

typedef complex<double> P;

P p[50];
int n;

double cr(P a,P b){
  return a.real()*b.imag()-a.imag()*b.real();
}

bool in(P a,P b,P c,P d){
  bool f[2]={};
  for(int i=0;i<3;i++){
    P pa[]={b,c,d};
    double c=cr(a-pa[i],pa[i+1]-pa[i]);
    if(fabs(c)>1e-9){
      f[c>0]=true;
    }
  }
  return !(f[0]&&f[1]);
}

bool ip(P cp){
  bool f=false;
  for(int px=0;px<n;px++){
    int nx=(px+1)%n;
    f|=cr(p[nx]-cp,p[px]-cp)>1e-9;
  }
  return !f;
}

int main(){
  while(cin>>n,n){
    for(int i=0;i<n;i++){
      int x,y;
      cin>>x>>y;
      p[i]=P(x,y);
    }
    int i;
    for(i=0;i<n;i++){
      for(int j=0;j<i;j++){
	for(int k=0;k<n;k++){
	  for(int l=0;l<k;l++){
	    if(fabs(cr(p[i]-p[j],p[k]-p[l]))<1e-9)continue;
	    double a=cr(p[k]-p[l],p[i]-p[l]);
	    double b=cr(p[k]-p[l],p[j]-p[l]);
	    P ic=p[i]+(p[j]-p[i])*a/(a-b);
	    int m;
	    for(m=0;m<n;m++){
	      if(!in(ic,p[m],p[(m+1)%n],p[(m+2)%n]))break;
	    }
	    if(m!=n&&ip(ic))goto end;
	  }
	}
      }
    }
  end:
    cout<<(i!=n)<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2280
memory_kb: 1160
final_rank: 11

code_snippet: #include<cmath>
#include<cstdio>
#include<vector>
#include<complex>
#include<algorithm>

#define pb       push_back
#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;

typedef complex<double> Point;
typedef vector<Point>   Polygon;

const double EPS=1e-7;

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){ pb(a), pb(b); }
};

class Segment:public Line{
public:
	Segment(){}
	Segment(const Point &a,const Point &b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

enum {CCW=1,CW=-1,ON=0};
int ccw(const Point &a,Point b,Point c){
	b-=a,c-=a;
	double rotdir=cross(b,c);
	if(rotdir>EPS)  return CCW;
	if(rotdir<-EPS) return CW;
	return ON;
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

bool cover(const Segment &s,const Point &p){
	return dot(s[0]-p,s[1]-p)<EPS;
}

bool intersect(const Line &l,const Line &m,Point &p){
	if(abs(cross(l[1]-l[0],m[1]-m[0]))>EPS
	|| abs(cross(l[1]-l[0],m[0]-l[0]))<EPS){
		double a1,b1,c1,a2,b2,c2;
		calc_abc(l,a1,b1,c1);
		calc_abc(m,a2,b2,c2);
		double det=a1*b2-a2*b1;
		if(abs(det)<EPS) p=l[0];
		else             p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		return true;
	}
	return false;
}

bool intersect(const Segment &s,const Segment &t,Point &p){
	bool flg;
	if(abs(cross(s[1]-s[0],t[1]-t[0]))<EPS && abs(cross(s[1]-s[0],t[0]-s[0]))<EPS){
		flg=(cover(s,t[0]) || cover(s,t[1]) || cover(t,s[0]) || cover(t,s[1]));
		if(!flg) return false;
	}

	if(flg || (ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1])<=0
			&& ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1])<=0)){
		double a1,b1,c1,a2,b2,c2;
		calc_abc(s,a1,b1,c1);
		calc_abc(t,a2,b2,c2);
		double det=a1*b2-a2*b1;
		if(abs(det)<EPS){ // s is parallel to t
			Point q[3]={s[0],s[1],t[0]};
			rep(i,3){
				if(cover(s,q[i]) && cover(t,q[i])){
					p=q[i];
					break;
				}
			}
		}
		else p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		return true;
	}
	return false;
}

bool cover(const Polygon &g,const Point &p){
	int n=g.size();
	bool in=false;
	rep(i,n){
		Point v1=g[i]-p,v2=g[(i+1)%n]-p;
		if(imag(v1)>imag(v2)) swap(v1,v2);
		// include lower vertex, not include upper vertex
		if(imag(v1)<EPS && EPS<imag(v2) && cross(v1,v2)>EPS) in=!in; // alternate
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS)	return true; // p is on g[i]-g[i+1]
	}
	return in;
}

bool isViewableAllVertices(const Polygon &g,const Point &p){
	int n=g.size();

	rep(i,n)if(abs(g[i]-p)>EPS){ // for each vertex g[i](!=p) in g
		Point u=g[i]-p; u/=abs(u);
		if(!cover(g,p+1e-5*u) || !cover(g,g[i]-1e-5*u)) return false;

		Segment s(p,g[i]);
		rep(j,n){ // for each side t in g
			Segment t(g[j],g[(j+1)%n]);
			Point q;
			// p-q-g[i] is on the same line (this order)
			if(intersect(s,t,q)){
				// if q != p, g[i]
				if(abs(p-q)>EPS && abs(g[i]-q)>EPS){
					if(!cover(g,q-1e-5*u) || !cover(g,q+1e-5*u)) return false;
				}
			}
		}
	}

	return true;
}

int main(){
	for(int n;scanf("%d",&n),n;){
		Polygon g;
		rep(i,n){
			int x,y; scanf("%d%d",&x,&y);
			g.pb(Point(x,y));
		}

		bool b=false;
		rep(i,n) rep(j,i) {
			Point p;
			Line l(g[i],g[(i+1)%n]),m(g[j],g[(j+1)%n]);
			if(intersect(l,m,p) && cover(g,p)){
				if(isViewableAllVertices(g,p)){ b=true; goto FOUND; }
			}
		}

		FOUND:
		puts(b?"1":"0");
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 800
final_rank: 3

code_snippet: #include<cmath>
#include<cstdio>
#include<vector>
#include<complex>
#include<algorithm>

#define pb       push_back
#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;

typedef complex<double> Point;
typedef vector<Point>   Polygon;

const double EPS=1e-7;

namespace std{
	bool operator <(const Point &a,const Point &b){
		return abs(real(a)-real(b))<EPS?(imag(a)+EPS<imag(b)):(real(a)+EPS<real(b));
	}
	bool operator >(const Point &a,const Point &b){
		return b<a;
	}
}

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){ pb(a), pb(b); }
};

class Segment:public Line{
public:
	Segment(){}
	Segment(const Point &a,const Point &b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

enum {CCW=1,CW=-1,ON=0};
int ccw(const Point &a,Point b,Point c){
	b-=a,c-=a;
	double rotdir=cross(b,c);
	if(rotdir>EPS)  return CCW;
	if(rotdir<-EPS) return CW;
	return ON;
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){	// l : ax+by+c=0
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

bool intersect(const Line &l,const Line &m,Point &p){
	if(abs(cross(l[1]-l[0],m[1]-m[0]))>EPS
	|| abs(cross(l[1]-l[0],m[0]-l[0]))<EPS){
		double a1,b1,c1,a2,b2,c2;
		calc_abc(l,a1,b1,c1);
		calc_abc(m,a2,b2,c2);
		double det=a1*b2-a2*b1;
		if(abs(det)<EPS) p=l[0]; // l==m
		else             p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		return true;
	}
	return false;
}

bool intersect(const Segment &s,const Segment &t,Point &p){
	if(max(real(s[0]),real(s[1]))<min(real(t[0]),real(t[1]))-EPS
	|| max(real(t[0]),real(t[1]))<min(real(s[0]),real(s[1]))-EPS
	|| max(imag(s[0]),imag(s[1]))<min(imag(t[0]),imag(t[1]))-EPS
	|| max(imag(t[0]),imag(t[1]))<min(imag(s[0]),imag(s[1]))-EPS) return false;

	if(ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1])<=0
	&& ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1])<=0){
		double a1,b1,c1,a2,b2,c2;
		calc_abc(s,a1,b1,c1);
		calc_abc(t,a2,b2,c2);
		double det=a1*b2-a2*b1;
		if(abs(det)<EPS){ // s is parallel to t
			Point q[3]={s[0],s[1],t[0]};
			rep(i,3){
				if(dot(q[i]-s[0],q[i]-s[1])<EPS && dot(q[i]-t[0],q[i]-t[1])<EPS){
					p=q[i];
					break;
				}
			}
		}
		else p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		return true;
	}
	return false;
}

bool contain(const Polygon &g,const Point &p){
	int n=g.size();
	bool in=false;
	rep(i,n){
		Point v1=g[i]-p,v2=g[(i+1)%n]-p;
		if(imag(v1)>imag(v2)) swap(v1,v2);
		// include lower vertex, not include upper vertex
		if(imag(v1)<EPS && EPS<imag(v2) && cross(v1,v2)>EPS) in=!in; // alternate
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS)	return true; // p is on g[i]-g[i+1]
	}
	return in;
}

bool isViewableAllVertices(const Polygon &g,const Point &p){
	int n=g.size();

	rep(i,n)if(abs(g[i]-p)>EPS){ // for each vertex g[i](!=p) in g
		Point u=g[i]-p; u/=abs(u);
		if(!contain(g,p+1e-5*u) || !contain(g,g[i]-1e-5*u)) return false;

		Segment s(p,g[i]);
		rep(j,n){ // for each side t in g
			Segment t(g[j],g[(j+1)%n]);
			Point q;
			// p-q-g[i] is on the same line (this order)
			if(intersect(s,t,q)){
				// if q != p, g[i]
				if(abs(p-q)>EPS && abs(g[i]-q)>EPS){
					if(!contain(g,q-1e-5*u) || !contain(g,q+1e-5*u)) return false;
				}
			}
		}
	}

	return true;
}

int main(){
	for(int n;scanf("%d",&n),n;){
		Polygon g;
		rep(i,n){
			int x,y; scanf("%d%d",&x,&y);
			g.pb(Point(x,y));
		}

		bool b=false;
		rep(i,n) rep(j,i) {
			Point p;
			Line l(g[i],g[(i+1)%n]),m(g[j],g[(j+1)%n]);
			if(intersect(l,m,p) && contain(g,p)){
				if(isViewableAllVertices(g,p)){ b=true; goto FOUND; }
			}
		}

		FOUND:
		puts(b?"1":"0");
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 796
final_rank: 1

code_snippet: #include<cmath>
#include<vector>
#include<complex>
#include<algorithm>

#define	pb			push_back
#define	rep(i,n)	for(int i=0;i<n;i++)

using namespace std;

typedef	complex<double>	Point;
typedef	vector<Point>	Polygon;

const double EPS=1e-7;

namespace std{
	bool operator <(const Point &a,const Point &b){
		return abs(real(a)-real(b))<EPS?(imag(a)+EPS<imag(b)):(real(a)+EPS<real(b));
	}
	bool operator >(const Point &a,const Point &b){
		return b<a;
	}
}

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){
		pb(a),pb(b);
	}
};

class Segment:public Line{
public:
	Segment(){}
	Segment(const Point &a,const Point &b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

enum {CCW=1,CW=-1,ON=0};
int ccw(const Point &a,Point b,Point c){
	b-=a,c-=a;
	double rotdir=cross(b,c);
	if(rotdir>EPS)		return CCW;
	if(rotdir<-EPS)		return CW;
	return ON;
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

bool intersect(const Line &l,const Line &m,Point *p=NULL){
	if(abs(cross(l[1]-l[0],m[1]-m[0]))>EPS
	|| abs(cross(l[1]-l[0],m[0]-l[0]))<EPS){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(l,a1,b1,c1);
			calc_abc(m,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS)	*p=l[0];
			else				*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool intersect(const Segment &s,const Segment &t,Point *p=NULL){
	if(max(real(s[0]),real(s[1]))<min(real(t[0]),real(t[1]))
	|| max(real(t[0]),real(t[1]))<min(real(s[0]),real(s[1]))
	|| max(imag(s[0]),imag(s[1]))<min(imag(t[0]),imag(t[1]))
	|| max(imag(t[0]),imag(t[1]))<min(imag(s[0]),imag(s[1])))	return false;

	if(ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1])<=0
	&& ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1])<=0){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(s,a1,b1,c1);
			calc_abc(t,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS){
				Point q[3]={s[0],s[1],t[0]};
				rep(i,3){
					if(dot(q[i]-s[0],q[i]-s[1])<EPS && dot(q[i]-t[0],q[i]-t[1])<EPS){
						*p=q[i];
						break;
					}
				}
			}
			else	*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool contain(const Polygon &g,const Point &p){
	int n=g.size();
	bool in=false;
	rep(i,n){
		Point v1=g[i]-p,v2=g[(i+1)%n]-p;
		if(imag(v1)>imag(v2))	swap(v1,v2);
		if(imag(v1)<EPS && EPS<imag(v2) && cross(v1,v2)>EPS)	in=!in;
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS)	return true;
	}
	return in;
}

#include<cstdio>

bool isViewableAllVertices(const Polygon &g,const Point &p){
	int n=g.size();

	rep(i,n)if(abs(g[i]-p)>EPS){
		Point u=g[i]-p; u/=abs(u);
		if(!contain(g,p+1e-5*u) || !contain(g,g[i]-1e-5*u))	return false;

		Segment s(p,g[i]);
		rep(j,n){
			Segment t(g[j],g[(j+1)%n]);
			Point q;
			if(intersect(s,t,&q)){
				if(abs(q-p)>EPS && abs(g[i]-q)>EPS){
					if(!contain(g,q-1e-5*u) || !contain(g,q+1e-5*u))	return false;
				}
			}
		}
	}

	return true;
}

int main(){
	for(int n;scanf("%d",&n),n;){
		Polygon g;
		rep(i,n){
			int x,y;	scanf("%d%d",&x,&y);
			g.pb(Point(x,y));
		}

		bool b=false;
		rep(i,n)rep(j,i){
			Point p;
			Line l(g[i],g[(i+1)%n]),m(g[j],g[(j+1)%n]);
			if(intersect(l,m,&p) && contain(g,p)){
				if(isViewableAllVertices(g,p)){ b=true; goto FOUND; }
			}
		}

		FOUND:
		puts(b?"1":"0");
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 796
final_rank: 1

code_snippet: #include<cmath>
#include<vector>
#include<complex>
#include<algorithm>

#define	pb			push_back
#define	rep(i,n)	for(int i=0;i<n;i++)

using namespace std;

typedef	complex<double>	Point;
typedef	vector<Point>	Polygon;

const double EPS=1e-7;

namespace std{
	bool operator <(const Point &a,const Point &b){
		return abs(real(a)-real(b))<EPS?(imag(a)+EPS<imag(b)):(real(a)+EPS<real(b));
	}
	bool operator >(const Point &a,const Point &b){
		return b<a;
	}
}

enum {CCW=1,CW=-1,ON=0};

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){
		pb(a),pb(b);
	}
};

class Segment:public Line{
public:
	Segment(){}
	Segment(const Point &a,const Point &b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

int ccw(const Point &a,Point b,Point c){
	b-=a,c-=a;
	double rotdir=cross(b,c);
	if(rotdir>EPS)		return CCW;
	if(rotdir<-EPS)		return CW;
	return ON;
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){	// l : ax+by+c=0
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

bool intersect(const Line &l,const Line &m,Point *p=NULL){
	// this routine also returns true in case "M is on L", etc,.
	if(abs(cross(l[1]-l[0],m[1]-m[0]))>EPS
	|| abs(cross(l[1]-l[0],m[0]-l[0]))<EPS){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(l,a1,b1,c1);
			calc_abc(m,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS)	*p=l[0];	// l==m
			else				*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool intersect(const Segment &s,const Segment &t,Point *p=NULL){
	if(max(real(s[0]),real(s[1]))<min(real(t[0]),real(t[1]))
	|| max(real(t[0]),real(t[1]))<min(real(s[0]),real(s[1]))
	|| max(imag(s[0]),imag(s[1]))<min(imag(t[0]),imag(t[1]))
	|| max(imag(t[0]),imag(t[1]))<min(imag(s[0]),imag(s[1])))	return false;

	if(ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1])<=0
	&& ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1])<=0){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(s,a1,b1,c1);
			calc_abc(t,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS){	// s is parallel to t
				Point q[3]={s[0],s[1],t[0]};
				rep(i,3){
					if(dot(q[i]-s[0],q[i]-s[1])<EPS && dot(q[i]-t[0],q[i]-t[1])<EPS){
						*p=q[i];
						break;
					}
				}
			}
			else	*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool contain(const Polygon &g,const Point &p){
	int n=g.size();
	bool in=false;
	rep(i,n){
		Point v1=g[i]-p,v2=g[(i+1)%n]-p;
		if(imag(v1)>imag(v2))	swap(v1,v2);
		// include lower vertex, not include upper vertex
		if(imag(v1)<EPS && EPS<imag(v2) && cross(v1,v2)>EPS)	in=!in;	// alternate
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS)	return true;	// p is on g[i]-g[i+1]
	}
	return in;
}

#include<cstdio>

bool isViewableAllVertices(const Polygon &g,const Point &p){
	int n=g.size();

	rep(i,n)if(abs(g[i]-p)>EPS){	// for each vertex g[i](!=p) in g
		Point u=g[i]-p; u/=abs(u);
		if(!contain(g,p+1e-5*u) || !contain(g,g[i]-1e-5*u))	return false;

		Segment s(p,g[i]);
		rep(j,n){	// for each side t in g
			Segment t(g[j],g[(j+1)%n]);
			Point q;
			// p-q-g[i] is on the same line (this order)
			if(intersect(s,t,&q)){
				// if q != p, g[i]
				if(abs(q-p)>EPS && abs(g[i]-q)>EPS){
					if(!contain(g,q-1e-5*u) || !contain(g,q+1e-5*u))	return false;
				}
			}
		}
	}

	return true;
}

int main(){
	for(int n;scanf("%d",&n),n;){
		Polygon g;
		rep(i,n){
			int x,y;	scanf("%d%d",&x,&y);
			g.pb(Point(x,y));
		}

		bool b=false;
		rep(i,n)rep(j,i){
			Point p;
			Line l(g[i],g[(i+1)%n]),m(g[j],g[(j+1)%n]);
			if(intersect(l,m,&p) && contain(g,p)){
				if(isViewableAllVertices(g,p)){ b=true; goto FOUND; }
			}
		}

		FOUND:
		puts(b?"1":"0");
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 800
final_rank: 3

code_snippet: #include<cmath>
#include<vector>
#include<complex>
#include<algorithm>

#define	pb			push_back
#define	rep(i,n)	for(int i=0;i<n;i++)

using namespace std;

typedef	complex<double>	Point;
typedef	vector<Point>	Polygon;

namespace std{
	bool operator <(const Point &a,const Point &b){
		return (real(a)==real(b))?(imag(a)<imag(b)):(real(a)<real(b));
	}
	bool operator >(const Point &a,const Point &b){
		return b<a;
	}
}

enum {CCW=1,CW=-1,ON=0};
const double EPS=1e-7;

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){
		pb(a),pb(b);
	}
};

class Segment:public Line{
public:
	Segment(){}
	Segment(const Point &a,const Point &b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

int ccw(const Point &a,Point b,Point c){
	b-=a,c-=a;
	double rotdir=cross(b,c);
	if(rotdir>EPS)		return CCW;
	if(rotdir<-EPS)		return CW;
	return ON;
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

bool intersect(const Line &l,const Line &m,Point *p=NULL){
	if(abs(cross(l[1]-l[0],m[1]-m[0]))>EPS
	|| abs(cross(l[1]-l[0],m[0]-l[0]))<EPS){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(l,a1,b1,c1);
			calc_abc(m,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS)	*p=l[0];
			else				*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool intersect(const Segment &s,const Segment &t,Point *p=NULL){
	if(max(real(s[0]),real(s[1]))<min(real(t[0]),real(t[1]))
	|| max(real(t[0]),real(t[1]))<min(real(s[0]),real(s[1]))
	|| max(imag(s[0]),imag(s[1]))<min(imag(t[0]),imag(t[1]))
	|| max(imag(t[0]),imag(t[1]))<min(imag(s[0]),imag(s[1])))	return false;

	if(ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1])<=0
	&& ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1])<=0){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(s,a1,b1,c1);
			calc_abc(t,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS){	// s is parallel to t
				Point q[3]={s[0],s[1],t[0]};
				rep(i,3){
					if(dot(q[i]-s[0],q[i]-s[1])<EPS && dot(q[i]-t[0],q[i]-t[1])<EPS){
						*p=q[i];
						break;
					}
				}
			}
			else	*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool contain(const Polygon &g,const Point &p){
	int n=g.size();
	bool in=false;
	rep(i,n){
		Point v1=g[i]-p,v2=g[(i+1)%n]-p;
		if(imag(v1)>imag(v2))	swap(v1,v2);
		if(imag(v1)<EPS && EPS<imag(v2) && cross(v1,v2)<-EPS)	in=!in;
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS)	return true;
	}
	return in;
}

#include<cstdio>

int main(){
	for(int n;scanf("%d",&n),n;){
		Polygon g;
		rep(i,n){
			int x,y;	scanf("%d%d",&x,&y);
			g.pb(Point(x,y));
		}

		vector<Point> candi;
		rep(i,n)rep(j,i){
			Line l(g[i],g[(i+1)%n]),m(g[j],g[(j+1)%n]);
			Point p;
			if(intersect(l,m,&p) && contain(g,p))	candi.pb(p);
		}

		rep(k,candi.size()){
			bool b=true;
			Point p=candi[k];
			rep(i,n)if(abs(g[i]-p)>EPS){
				Point u=g[i]-p; u/=abs(u);
				if(!contain(g,p+1e-5*u) || !contain(g,g[i]-1e-5*u)){ b=false; break; }

				Segment s(p,g[i]);
				rep(j,n){
					Segment t(g[j],g[(j+1)%n]);
					Point q;
					if(intersect(s,t,&q)){
						if(abs(q-p)>EPS && abs(g[i]-q)>EPS){
							if(!contain(g,q-1e-5*u) || !contain(g,q+1e-5*u)){
								b=false;
								break;
							}
						}
					}
				}
				if(!b)	break;
			}
			if(b)	goto FOUND;
		}
		goto NOT_FOUND;

		FOUND:
		puts("1");
		continue;

		NOT_FOUND:
		puts("0");
	}

	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 828
final_rank: 7

code_snippet: #include<cmath>
#include<vector>
#include<complex>
#include<algorithm>

#define	pb			push_back
#define	rep(i,n)	for(int i=0;i<n;i++)

using namespace std;

typedef	complex<double>	Point;
typedef	vector<Point>	Polygon;

namespace std{
	bool operator <(const Point &a,const Point &b){
		return (real(a)==real(b))?(imag(a)<imag(b)):(real(a)<real(b));
	}
	bool operator >(const Point &a,const Point &b){
		return b<a;
	}
}

enum {CCW=1,CW=-1,ON=0};
const double EPS=1e-7;

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){
		pb(a),pb(b);
	}
};

class Segment:public Line{
public:
	Segment(){}
	Segment(const Point &a,const Point &b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

int ccw(const Point &a,Point b,Point c){
	b-=a,c-=a;
	double rotdir=cross(b,c);
	if(rotdir>EPS)		return CCW;
	if(rotdir<-EPS)		return CW;
	return ON;
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

bool intersect(const Line &l,const Line &m,Point *p=NULL){
	if(abs(cross(l[1]-l[0],m[1]-m[0]))>EPS
	|| abs(cross(l[1]-l[0],m[0]-l[0]))<EPS){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(l,a1,b1,c1);
			calc_abc(m,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS)	*p=l[0];
			else				*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool intersect(const Segment &s,const Segment &t,Point *p=NULL){
	if(max(real(s[0]),real(s[1]))<min(real(t[0]),real(t[1]))
	|| max(real(t[0]),real(t[1]))<min(real(s[0]),real(s[1]))
	|| max(imag(s[0]),imag(s[1]))<min(imag(t[0]),imag(t[1]))
	|| max(imag(t[0]),imag(t[1]))<min(imag(s[0]),imag(s[1])))	return false;

	if(ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1])<=0
	&& ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1])<=0){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(s,a1,b1,c1);
			calc_abc(t,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS){	// s is parallel to t
				Point q[3]={s[0],s[1],t[0]};
				rep(i,3){
					if(dot(q[i]-s[0],q[i]-s[1])<EPS && dot(q[i]-t[0],q[i]-t[1])<EPS){
						*p=q[i];
						break;
					}
				}
			}
			else	*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool contain(const Polygon &g,const Point &p){
	int n=g.size();
	bool in=false;
	rep(i,n){
		Point v1=g[i]-p,v2=g[(i+1)%n]-p;
		double eps=EPS;
		if(imag(v1)>imag(v2))	swap(v1,v2),eps=-eps;
		if(imag(v1)<eps && eps<imag(v2) && cross(v1,v2)<-EPS)	in=!in;
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS)	return true;
	}
	return in;
}

#include<cstdio>

int main(){
	for(int n;scanf("%d",&n),n;){
		Polygon g;
		rep(i,n){
			int x,y;	scanf("%d%d",&x,&y);
			g.pb(Point(x,y));
		}

		vector<Point> candi;
		rep(i,n)rep(j,i){
			Line l(g[i],g[(i+1)%n]),m(g[j],g[(j+1)%n]);
			Point p;
			if(intersect(l,m,&p) && contain(g,p))	candi.pb(p);
		}

		rep(k,candi.size()){
			bool b=true;
			Point p=candi[k];
			rep(i,n)if(abs(g[i]-p)>EPS){
				Point u=g[i]-p; u/=abs(u);
				if(!contain(g,p+1e-5*u) || !contain(g,g[i]-1e-5*u)){ b=false; break; }

				Segment s(p,g[i]);
				rep(j,n){
					Segment t(g[j],g[(j+1)%n]);
					Point q;
					if(intersect(s,t,&q)){
						if(abs(q-p)>EPS && abs(g[i]-q)>EPS){
							if(!contain(g,q-1e-5*u) || !contain(g,q+1e-5*u)){
								b=false;
								break;
							}
						}
					}
				}
				if(!b)	break;
			}
			if(b)	goto FOUND;
		}
		goto NOT_FOUND;

		FOUND:
		puts("1");
		continue;

		NOT_FOUND:
		puts("0");
	}

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 828
final_rank: 5

code_snippet: #include<cmath>
#include<vector>
#include<complex>
#include<algorithm>

#define	pb			push_back
#define	rep(i,n)	for(int i=0;i<n;i++)

using namespace std;

typedef	complex<double>	Point;
typedef	vector<Point>	Polygon;

namespace std{
	bool operator <(const Point &a,const Point &b){
		return (real(a)==real(b))?(imag(a)<imag(b)):(real(a)<real(b));
	}
	bool operator >(const Point &a,const Point &b){
		return b<a;
	}
}

enum {CCW=1,CW=-1,ON=0};
const double EPS=1e-7;

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){
		pb(a),pb(b);
	}
};

class Segment:public Line{
public:
	Segment(){}
	Segment(const Point &a,const Point &b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

int ccw(const Point &a,Point b,Point c){
	b-=a,c-=a;
	double rotdir=cross(b,c);
	if(rotdir>EPS)		return CCW;
	if(rotdir<-EPS)		return CW;
	return ON;
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){	// l : ax+by+c=0
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

bool intersect(const Line &l,const Line &m,Point *p=NULL){
	// this routine also returns true in case "M is on L", etc,.
	if(abs(cross(l[1]-l[0],m[1]-m[0]))>EPS
	|| abs(cross(l[1]-l[0],m[0]-l[0]))<EPS){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(l,a1,b1,c1);
			calc_abc(m,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS)	*p=l[0];	// l==m
			else				*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool intersect(const Segment &s,const Segment &t,Point *p=NULL){
	if(max(real(s[0]),real(s[1]))<min(real(t[0]),real(t[1]))
	|| max(real(t[0]),real(t[1]))<min(real(s[0]),real(s[1]))
	|| max(imag(s[0]),imag(s[1]))<min(imag(t[0]),imag(t[1]))
	|| max(imag(t[0]),imag(t[1]))<min(imag(s[0]),imag(s[1])))	return false;

	if(ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1])<=0
	&& ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1])<=0){
		if(p){
			double a1,b1,c1,a2,b2,c2;
			calc_abc(s,a1,b1,c1);
			calc_abc(t,a2,b2,c2);
			double det=a1*b2-a2*b1;
			if(abs(det)<EPS){	// s is parallel to t
				Point q[3]={s[0],s[1],t[0]};
				rep(i,3){
					if(dot(q[i]-s[0],q[i]-s[1])<EPS && dot(q[i]-t[0],q[i]-t[1])<EPS){
						*p=q[i];
						break;
					}
				}
			}
			else	*p=Point(b1*c2-b2*c1,a2*c1-a1*c2)/det;
		}
		return true;
	}
	return false;
}

bool contain(const Polygon &g,const Point &p){
	int n=g.size();
	bool in=false;
	rep(i,n){
		Point v1=g[i]-p,v2=g[(i+1)%n]-p;
		double eps=EPS;
		if(imag(v1)>imag(v2))	swap(v1,v2),eps=-eps;
		// include g[i], not include g[i+1]
		if(imag(v1)<eps && eps<imag(v2) && cross(v1,v2)<-EPS)	in=!in;	// alternate
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS)	return true;	// p is on g[i]-g[i+1]
	}
	return in;
}

#include<cstdio>

int main(){
	for(int n;scanf("%d",&n),n;){
		Polygon g;
		rep(i,n){
			int x,y;	scanf("%d%d",&x,&y);
			g.pb(Point(x,y));
		}

		vector<Point> candi;
		rep(i,n)rep(j,i){
			Line l(g[i],g[(i+1)%n]),m(g[j],g[(j+1)%n]);
			Point p;
			if(intersect(l,m,&p) && contain(g,p))	candi.pb(p);
		}

		rep(k,candi.size()){
			bool b=true;
			Point p=candi[k];
			rep(i,n)if(abs(g[i]-p)>EPS){	// for each vertex g[i](!=p) in g
				Point u=g[i]-p; u/=abs(u);
				if(!contain(g,p+1e-5*u) || !contain(g,g[i]-1e-5*u)){ b=false; break; }

				Segment s(p,g[i]);
				rep(j,n){	// for each side t in g
					Segment t(g[j],g[(j+1)%n]);
					Point q;
					// p-q-g[i] is on the same line (this order)
					if(intersect(s,t,&q)){
						// if q != p, g[i]
						if(abs(q-p)>EPS && abs(g[i]-q)>EPS){
							if(!contain(g,q-1e-5*u) || !contain(g,q+1e-5*u)){
								b=false;
								break;
							}
						}
					}
				}
				if(!b)	break;
			}
			if(b)	goto FOUND;
		}
		goto NOT_FOUND;

		FOUND:
		puts("1");
		continue;

		NOT_FOUND:
		puts("0");
	}

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 828
final_rank: 5

code_snippet: #include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<complex>
using namespace std;

#define REP(i,n) for(int i = 0; i < (int)(n); i++)

typedef complex<double> P;
const double PI = acos(-1.0);
const double EPS = 1e-10;

double dot(P a, P b) {return real( conj(a)*b);}
double cross(P a, P b) {return imag( conj(a)*b);}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > EPS)   return +1;       // counter clockwise
  if (cross(b, c) < -EPS)   return -1;       // clockwise
  if (dot(b, c) < -EPS)     return +2;       // c--a--b on line
  if (norm(b) < norm(c) - EPS) return -2; // a--b--c on line
  return 0;                               // a--c--b on line (or b == c)
}

bool IsIntersectLL(P a,P b,P c,P d){
  return abs(cross(b-a, d-c)) > EPS || // non-parallel
    abs(cross(b-a, c-a)) < EPS;   // same line
}
bool IsIntersectSS(P a1, P a2, P b1, P b2) {
  return ccw(a1,a2,b1) * ccw(a1,a2,b2) <= 0 &&
    ccw(b1,b2,a1) * ccw(b1,b2,a2) <= 0;
}
P IntersectionLL(P a1, P a2, P b1, P b2) {
  P a = a2 - a1; P b = b2 - b1;
  double A = cross(b, b1-a1);
  double B = cross(b, a);
  if( abs(A) < EPS && abs(B) < EPS ) return a1; // same line
  return a1 + a * A / B;
}

bool SeeAll( const vector<P> &polygon, P p ) {
  int N = polygon.size() - 1;
  for(int i = 0; i < N; i++) {
    int count = 0;
    for(int j = 0; j < N; j++) {
      if( IsIntersectSS( p, polygon[i], polygon[j], polygon[j+1]) )
        count++;
    }
    if( count != 2 ) return false;
  }
  return true;
}

int main() {
  for(int N; scanf("%d", &N), N; ) {
    vector<P> polygon;
    REP(n, N) {
      int x, y;
      scanf("%d%d", &x, &y);
      polygon.push_back( P(x,y) );
    }

    polygon.push_back( polygon[0] );

    int ans = 0;
    for(int i = 0; i < N; i++){
      for(int j = i+1; j < N; j++){
        if( IsIntersectLL( polygon[i], polygon[i+1], polygon[j], polygon[j+1] ) ){
          P can = IntersectionLL(polygon[i], polygon[i+1], polygon[j], polygon[j+1]);

          for(int k = 0; k < 10; k++) {
            if( SeeAll( polygon, can + polar(0.00001, 2 * PI / k) ) ) {
              ans = 1;
              goto END;
            }

          }

        }
      }
    }

  END:
    printf("%d\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 3830
memory_kb: 940
final_rank: 14