Problem:
ねこまっしぐら

あるところに、高い塀に囲まれた大きなお屋敷がありました。そのお屋敷の主人は猫がとても大好きで、時折やってくる猫たちのために、いつもおいしいごはんを用意していました。お腹を空かせた猫たちは、高い塀をひょいと飛び越え、お屋敷の至る所に置いてあるごはんにまっしぐらに駆け寄るのでした。

ある日主人は、屋敷の中で何匹かの猫が倒れているのを見つけました。猫たちはごはんを探して屋敷の中を縦横無尽に走り回ったので、ぶつかったり転んだりしてしまったのです。主人は猫たちの安全を考えて、ごはんの置き場所を工夫することにしました。

上空から見ると、このお屋敷の塀は多角形をなしています。主人は猫たちがごはんを見つけやすいように、敷地内の中でも、多角形の頂点にあたる場所だけにごはんを置くことにしました。また猫たちは気まぐれなので、多角形の周上のどの点からお屋敷に入ってくるかは予想できません。そこで主人は、猫がどの点から入ったとしても、その点から直進していずれかのごはんにたどり着けるように、ごはんを配置することも決めました。

すべての頂点にごはんを配置すれば、この条件を満たすことができます。しかし、ごはんを補充して回るのは大変なので、主人はできるだけ少ない数の頂点にごはんを配置したいと思いました。さて、主人は最低何箇所にごはんを配置する必要があるでしょうか。

お屋敷の塀を表す多角形を入力とし、ごはんを配置する頂点の数の最小値を求めるプログラムを作成して下さい。ただし、猫は多角形の内部のみを直進できるものとします（辺は多角形の内部に含めるものとします）。

入力

入力は複数のデータセットからなる。入力の終わりはゼロ１つの行で示される。各データセットは以下の形式で与えられる。

n
x1 y1
x2 y2
...
xn yn

１行目に多角形の頂点の数 n (3 ≤ n ≤ 16) が与えられる。続く n 行に多角形の頂点の座標が与えられる。n 行のそれぞれは、１つの空白で区切られた２つの整数からなる。xi (-1000 ≤ xi ≤ 1000) は i 番目の頂点の x 座標、yi (-1000 ≤ yi ≤ 1000) は i 番目の頂点の y 座標を示す。多角形の頂点は、隣り合った頂点を反時計回りに訪問するような順番で与えられる。

データセットの数は 20 を超えない。

出力

各データセットごとに、ご飯を配置する頂点の数を１行に出力する。

入力例

8
0 0
3 2
6 2
8 6
6 5
7 7
0 4
3 4
8
0 0
5 3
5 2
4 1
6 1
8 6
6 4
2 4
0

出力例

1
2

Solution in C++ (judge verdict: Wrong Answer)

#include<bits/stdc++.h>
using namespace std;
typedef complex<double> P;

struct data{
  double d;
  P p;
  bool operator < (const data &a)const{
    return d < a.d;
  }
};

double eps=1e-8;
double PI=acos(-1);

bool eq(double a,double b){return (b-a<eps&&a-b<eps);}
bool eq(P a,P b){return (abs(a-b)<eps);}
bool onSegment(P a,P b,P p){
  return eq( abs(a-b) , abs(a-p) + abs(b-p) );
}

double dot(P a,P b){return real(b*conj(a));}
double cross(P a,P b){return imag(b*conj(a));}
P getPoint(P a,P b,P c,P d){
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}
bool isParallel(P a,P b,P c,P d){
  return eq(0,cross(a-b,c-d));
}
int n;
P t[16];
vector<P> A,B;

double Arg(P a,P b,P c){
  b-=a,c-=a;
  return arg(c*conj(b));
}
 
bool inPolygon(P p){
  double sum=0;  
  for(int i=0;i<n;i++){
    P a=t[i],b=t[(i+1==n?0:i+1)];
    if(onSegment(a,b,p))return true;
    sum+= Arg(p,a,b);
  }
  if( abs(sum) < eps )return false;
  else  return true;
}

bool inPolygon(P a,P b){
  vector< data > v;
  for(int i=0;i<n;i++){
    P c=t[i],d=t[(i+1)%n];
    if(isParallel(a,b,c,d))continue;
    P sp=getPoint(a,b,c,d);
    if(!onSegment(a,b,sp))continue;
    if(!onSegment(c,d,sp))continue;
    v.push_back((data){ abs(a-sp) , sp});
  }
  v.push_back( (data){0,a} );
  v.push_back( (data){abs(a-b),b} );
  sort(v.begin(),v.end());

  for(int i=0;i<(int)v.size();i++){
    if( !inPolygon(v[i].p) )return false;
    if(i&& !inPolygon( (v[i].p+v[i-1].p)*0.5 ) )return false;
  }
  return true;
}


int solve(){
  A.clear();B.clear();
  for(int i=0;i<n;i++){
    P a=t[i],b=t[(i+1)%n];
    vector< data > v;
    for(int j=0;j<n;j++){
      P c=t[j],d=t[(j+1)%n];
      if( eq( 0, cross(a-b,c-d) ) )continue;
      P np = getPoint(a,b,c,d);
      if(!onSegment(a,b,np))continue;
      v.push_back((data){ abs(np-a) , np } );
    }
    sort(v.begin(),v.end());
    A.push_back(a);
    for(int j=0;j<(int)v.size();j++){
      A.push_back(v[j].p);
    }
  }

  for(int i=0;i<(int)A.size();i++){
    P a=A[i],b=A[(i+1)%A.size()];
    B.push_back(a);
    P c=(a+b)*0.5;
    if( inPolygon(c) )B.push_back(c);
  }
  
  bool g[1000][16]={};
  for(int i=0;i<(int)B.size();i++){
    P a=B[i];
    for(int j=0;j<n;j++){
      g[i][j]=inPolygon(a,t[j]);
      //      cout<<a<<' '<<t[j]<<' '<<g[i][j]<<endl;        ////////////////
    }
  }
  
  vector<int> G[9];
  for(int i=0;i<(1<<n);i++){
    int cnt=__builtin_popcount(i);
    if(cnt<=8)G[cnt].push_back(i);
  }
  
  for(int i=1;i<=8;i++){
    for(int j=0;j<(int)G[i].size();j++){
      int bit=G[i][j];
      int cnt=0;
      for(int k=0;k<(int)B.size();k++){
        bool flg=false;
        for(int l=0;l<n;l++){
          if(bit>>l&1){
            flg|=g[k][l];
          }
        }
        if(flg)cnt++;
      }
      if(cnt==(int)B.size()){
         return i;
      }
    }
  }
  assert(0);
  return 9;
}

int main(){
  while(1){
    cin>>n;
    if(n==0)break;
    for(int i=0;i<n;i++){
      double x,y;
      cin>>x>>y;
      t[i]=P(x,y);
    }
    cout<<solve()<<endl;
  }
  return 0;
}