Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define gc c=getchar()
- #define r(x) read(x)
- template<typename T>
- inline void read(T&x){
- x=0;T k=1;char gc;
- while(!isdigit(c)){if(c=='-')k=-1;gc;}
- while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
- }
- #define db double
- const db eps=1e-19;
- const db INF=1e9;
- const int N=1005;
- inline int dcmp(const db &x){
- if(fabs(x)<eps)return 0;
- return x>0?1:-1;
- }
- struct Point{
- db x,y;
- inline Point(){}
- inline Point(const db &_x,const db &_y):x(_x),y(_y){}
- };
- #define Vec Point
- inline Vec operator +(const Vec &a,const Vec &b){
- return Vec(a.x+b.x,a.y+b.y);
- }
- inline Vec operator -(const Vec &a,const Vec &b){
- return Vec(a.x-b.x,a.y-b.y);
- }
- inline void operator +=(Vec &a,const Vec &b){
- a.x+=b.x,a.y+=b.y;
- }
- inline void operator -=(Vec &a,const Vec &b){
- a.x-=b.x,a.y-=b.y;
- }
- inline Vec operator *(const Vec &a,const db &b){
- return Vec(a.x*b,a.y*b);
- }
- inline Vec operator /(const Vec &a,const db &b){
- return Vec(a.x/b,a.y/b);
- }
- inline db Cross(const Vec &a,const Vec &b){
- return a.x*b.y-a.y*b.x;
- }
- inline db Angle(const Vec &a){
- return atan2(a.y,a.x);
- }
- struct Line{
- Point S;
- Vec v;
- db theta;
- int id;
- inline Line(){}
- inline Line(const Point &A,const Vec &a,const int &x):S(A),v(a),theta(Angle(a)),id(x){}
- };
- #define Seg Line
- inline bool operator < (const Line &A,const Line &B){
- double alpha=A.theta-B.theta;
- if(dcmp(alpha))return dcmp(alpha)==-1;
- return dcmp(Cross(A.v,B.S-A.S))==-1;
- }
- inline Point LineCross(const Line &a,const Line &b){
- Vec v=a.S-b.S;
- db t=Cross(b.v,v)/Cross(a.v,b.v);
- return a.S+a.v*t;
- }
- //on the right or not
- inline bool Direction(const Line &a,const Point &A){
- return dcmp(Cross(a.v,A-a.S))==-1;
- }
- inline Point MidPoint(const Point &A,const Point &B){
- return (A+B)/2;
- }
- inline Vec Normal(const Vec &a){
- return Vec(-a.y,a.x);
- }
- vector<int>G[N];
- inline void addedge(int x,int y){
- G[x].push_back(y);
- }
- Point S;
- int n,maxx,maxy,now;
- int Q[N];
- int head,tail;
- inline void Half(Line *A,int n,int id){
- sort(A+1,A+n+1);
- Q[0]=1;
- head=tail=0;
- for(int i=2;i<=n;++i){
- if(!dcmp(A[i].theta-A[i-1].theta))continue;
- while(head<tail&&Direction(A[i],LineCross(A[Q[tail]],A[Q[tail-1]])))
- --tail;
- while(head<tail&&Direction(A[i],LineCross(A[Q[head]],A[Q[head+1]])))
- ++head;
- Q[++tail]=i;
- }
- while(head<tail&&Direction(A[Q[head]],LineCross(A[Q[tail]],A[Q[tail-1]])))
- --tail;
- while(head<tail&&Direction(A[Q[tail]],LineCross(A[Q[head]],A[Q[head+1]])))
- ++head;
- for(int i=head;i<=tail;++i){
- addedge(id,A[Q[i]].id);
- }
- if(!now){
- for(int i=head;i<=tail;++i){
- if(Direction(A[Q[i]],S))return ;
- }
- now=id;
- }
- }
- int dis[N];
- bool vis[N];
- inline int bfs(int s,int t){
- memset(vis,0,n+1);
- vis[s]=1;
- dis[s]=0;
- head=0,tail=0;
- Q[0]=s;
- while(head<=tail){
- if(vis[t])return dis[t];
- int x=Q[head++];
- for(int i=0;i<G[x].size();++i){
- int v=G[x][i];
- if(!vis[v]){
- vis[v]=1;
- dis[v]=dis[x]+1;
- Q[++tail]=v;
- }
- }
- }
- // assert(0);
- }
- Point A[N];
- Line L[N];
- inline void solve(){
- Point a(0,0);
- Point b(maxx,0);
- Point c(maxx,maxy);
- Point d(0,maxy);
- now=0;
- for(int i=1;i<=n;++i){
- int tot=0;
- for(int j=1;j<=n;++j){
- if(j!=i){
- L[++tot]=Line(MidPoint(A[i],A[j]),Normal(A[j]-A[i]),j);
- }
- }
- L[++tot]=Line(a,Vec(1,0),0);
- L[++tot]=Line(b,Vec(0,1),0);
- L[++tot]=Line(c,Vec(-1,0),0);
- L[++tot]=Line(d,Vec(0,-1),0);
- G[i].clear();
- Half(L,tot,i);
- }
- printf("%d\n",bfs(now,0));
- }
- int main(){
- int T;r(T);
- while(T--){
- r(n),r(maxx),r(maxy),r(S.x),r(S.y);
- for(int i=1;i<=n;++i){
- r(A[i].x),r(A[i].y);
- }
- solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment