Advertisement
yicongli

LG3297

Mar 1st, 2019
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.70 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define gc c=getchar()
  6. #define r(x) read(x)
  7.  
  8. template<typename T>
  9. inline void read(T&x){
  10.     x=0;T k=1;char gc;
  11.     while(!isdigit(c)){if(c=='-')k=-1;gc;}
  12.     while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
  13. }
  14.  
  15. #define db double
  16.  
  17. const db eps=1e-19;
  18. const db INF=1e9;
  19. const int N=1005;
  20.  
  21. inline int dcmp(const db &x){
  22.     if(fabs(x)<eps)return 0;
  23.     return x>0?1:-1;
  24. }
  25.  
  26. struct Point{
  27.     db x,y;
  28.    
  29.     inline Point(){}
  30.     inline Point(const db &_x,const db &_y):x(_x),y(_y){}
  31.    
  32. };
  33.  
  34. #define Vec Point
  35.  
  36. inline Vec operator +(const Vec &a,const Vec &b){
  37.     return Vec(a.x+b.x,a.y+b.y);
  38. }
  39.  
  40. inline Vec operator -(const Vec &a,const Vec &b){
  41.     return Vec(a.x-b.x,a.y-b.y);
  42. }
  43.  
  44. inline void operator +=(Vec &a,const Vec &b){
  45.     a.x+=b.x,a.y+=b.y;
  46. }
  47.  
  48. inline void operator -=(Vec &a,const Vec &b){
  49.     a.x-=b.x,a.y-=b.y;
  50. }
  51.  
  52. inline Vec operator *(const Vec &a,const db &b){
  53.     return Vec(a.x*b,a.y*b);
  54. }
  55.  
  56. inline Vec operator /(const Vec &a,const db &b){
  57.     return Vec(a.x/b,a.y/b);
  58. }
  59.  
  60. inline db Cross(const Vec &a,const Vec &b){
  61.     return a.x*b.y-a.y*b.x;
  62. }
  63.  
  64. inline db Angle(const Vec &a){
  65.     return atan2(a.y,a.x);
  66. }
  67.  
  68. struct Line{
  69.     Point S;
  70.     Vec v;
  71.     db theta;
  72.     int id;
  73.    
  74.     inline Line(){}
  75.     inline Line(const Point &A,const Vec &a,const int &x):S(A),v(a),theta(Angle(a)),id(x){}
  76.    
  77. };
  78.  
  79. #define Seg Line
  80.  
  81. inline bool operator < (const Line &A,const Line &B){
  82.     double alpha=A.theta-B.theta;
  83.     if(dcmp(alpha))return dcmp(alpha)==-1;
  84.     return dcmp(Cross(A.v,B.S-A.S))==-1;
  85. }
  86.  
  87. inline Point LineCross(const Line &a,const Line &b){
  88.     Vec v=a.S-b.S;
  89.     db t=Cross(b.v,v)/Cross(a.v,b.v);
  90.     return a.S+a.v*t;
  91. }
  92. //on the right or not
  93. inline bool Direction(const Line &a,const Point &A){
  94.     return dcmp(Cross(a.v,A-a.S))==-1;
  95. }
  96.  
  97. inline Point MidPoint(const Point &A,const Point &B){
  98.     return (A+B)/2;
  99. }
  100.  
  101. inline Vec Normal(const Vec &a){
  102.     return Vec(-a.y,a.x);
  103. }
  104.  
  105. vector<int>G[N];
  106.  
  107. inline void addedge(int x,int y){
  108.     G[x].push_back(y);
  109. }
  110.  
  111. Point S;
  112. int n,maxx,maxy,now;
  113. int Q[N];
  114. int head,tail;
  115.  
  116. inline void Half(Line *A,int n,int id){
  117.     sort(A+1,A+n+1);
  118.     Q[0]=1;
  119.     head=tail=0;
  120.     for(int i=2;i<=n;++i){
  121.         if(!dcmp(A[i].theta-A[i-1].theta))continue;
  122.         while(head<tail&&Direction(A[i],LineCross(A[Q[tail]],A[Q[tail-1]])))
  123.         --tail;
  124.         while(head<tail&&Direction(A[i],LineCross(A[Q[head]],A[Q[head+1]])))
  125.         ++head;
  126.         Q[++tail]=i;
  127.     }
  128.     while(head<tail&&Direction(A[Q[head]],LineCross(A[Q[tail]],A[Q[tail-1]])))
  129.     --tail;
  130.     while(head<tail&&Direction(A[Q[tail]],LineCross(A[Q[head]],A[Q[head+1]])))
  131.     ++head;
  132.     for(int i=head;i<=tail;++i){
  133.         addedge(id,A[Q[i]].id);
  134.     }
  135.     if(!now){
  136.         for(int i=head;i<=tail;++i){
  137.             if(Direction(A[Q[i]],S))return ;
  138.         }
  139.         now=id;
  140.     }
  141. }
  142.  
  143. int dis[N];
  144. bool vis[N];
  145.  
  146. inline int bfs(int s,int t){
  147.     memset(vis,0,n+1);
  148.     vis[s]=1;
  149.     dis[s]=0;
  150.     head=0,tail=0;
  151.     Q[0]=s;
  152.     while(head<=tail){
  153.         if(vis[t])return dis[t];
  154.         int x=Q[head++];
  155.         for(int i=0;i<G[x].size();++i){
  156.             int v=G[x][i];
  157.             if(!vis[v]){
  158.                 vis[v]=1;
  159.                 dis[v]=dis[x]+1;
  160.                 Q[++tail]=v;
  161.             }
  162.         }
  163.     }
  164. //  assert(0);
  165. }
  166.  
  167. Point A[N];
  168. Line L[N];
  169.  
  170. inline void solve(){
  171.     Point a(0,0);
  172.     Point b(maxx,0);
  173.     Point c(maxx,maxy);
  174.     Point d(0,maxy);
  175.     now=0;
  176.     for(int i=1;i<=n;++i){
  177.         int tot=0;
  178.         for(int j=1;j<=n;++j){
  179.             if(j!=i){
  180.                 L[++tot]=Line(MidPoint(A[i],A[j]),Normal(A[j]-A[i]),j);
  181.             }
  182.         }
  183.         L[++tot]=Line(a,Vec(1,0),0);
  184.         L[++tot]=Line(b,Vec(0,1),0);
  185.         L[++tot]=Line(c,Vec(-1,0),0);
  186.         L[++tot]=Line(d,Vec(0,-1),0);
  187.         G[i].clear();
  188.         Half(L,tot,i);
  189.     }
  190.     printf("%d\n",bfs(now,0));
  191. }
  192.  
  193. int main(){
  194.     int T;r(T);
  195.     while(T--){
  196.         r(n),r(maxx),r(maxy),r(S.x),r(S.y);
  197.         for(int i=1;i<=n;++i){
  198.             r(A[i].x),r(A[i].y);
  199.         }
  200.         solve();
  201.     }
  202.     return 0;
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement