连接

hdu 4643 GSM(暴力)

GSM

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 569    Accepted Submission(s): 182

Problem Description
Xiao Ming is traveling around several cities by train. And the time on the train is very boring, so Xiao Ming will use the mobile Internet. We all know that mobile phone receives the signal from base station and it will change the base station when moving on the train. Xiao Ming would like to know how many times the base station will change from city A to city B. Now, the problem is simplified. We assume the route of train is straight, and the mobile phone will receive the signal from the nearest base station. 
 

 

Input
Multiple cases. For each case, The first line: N(3<=N<=50) - the number of cities, M(2<=M<=50) - the number of base stations. Then there are N cities with coordinates of (x, y) and M base stations with coordinates of (x, y) - (0<=x<=1000, 0<=y<=1000, both x and y is integer).Then there is a number : K, the next, there are K queries, for each query, each line, there are two numbers: a, b.
 

 

Output
For each query, tell Xiao Ming how many times the base station will change from city a to city b.
 

 

Sample Input
4 4 0 2 1 3 1 0 2 0 1 2 1 1 2 2 2 1 4 1 2 1 3 1 4 3 4
 

 

Sample Output
0 1 2 1
Hint
The train way from a to b will not cross the point with the same distance from more than 2 base stations. (For the distance d1 and d2, if fabs(d1-d2)<1e-7, we think d1 == d2). And every city exactly receive signal from just one base station.
 

 

Source
 

 

zhuyuanchen520
 
 
 
 
想法:
  
  假设是a  city  到 b  city;
 
  首先先找到离起点最近的电台!
 
  然后以这个点为辅助点去找下一个点(而下一个点该怎么确定呢??);
 
  我们可以这样做:枚举其他所有的电台,与辅助点连接做中垂线,交于线段一点,枚举完后找到最靠左边的那个点
 
  并把这个点叫做关键点,之后如此重复,不断的更新这个关键点,每更新一次次数ans++,直到这个关键点移出了 b 点!!
 
 
 
  
  1 #include<stdio.h>  
  2 #include<string.h>
  3 #include<cmath>  
  4 #include<cstdlib>  
  5 #include<algorithm>  
  6 using namespace std;  
  7 #define pi acos(-1.0)  
  8 #define eps 1e-7
  9 #define oo 99999998
 10 struct point
 11 {
 12     double x,y;
 13      point(double _x = 0.0,double _y = 0.0)
 14     {
 15         x =_x;
 16         y =_y;
 17     }
 18     point operator -(const point &b)const
 19     {
 20         return point(x - b.x, y - b.y);
 21     }
 22     point operator +(const point &b)const
 23     {
 24         return point(x +b.x, y + b.y);
 25     }
 26     point operator |(const double &b)const
 27     {
 28         return point(x*b, y*b);
 29     }
 30     double operator ^(const point &b)const
 31     {
 32         return x*b.y - y*b.x;
 33     }
 34     double operator *(const point &b)const
 35     {
 36         return x*b.x + y*b.y;
 37     }
 38     
 39     void input()
 40     {
 41         scanf("%lf%lf",&x,&y);
 42     }
 43 }; 
 44 
 45 int dcmp(double a)
 46 {
 47     if(fabs(a)<eps)return 0;
 48     if(a>0)return 1;
 49     else return -1; 
 50 }
 51 
 52 double len(point a)
 53 {
 54      return sqrt(a*a);
 55 }
 56 
 57 double Angle(point a,point b)
 58 {
 59     double ans=acos((a*b)/len(a)/len(b));
 60     return ans;
 61 }
 62 
 63 point getjiaodian(point p,point v,point q,point w)
 64 {
 65     point u;
 66     u=p-q;
 67     double t=(w^u)/(v^w);
 68     v.x=t*v.x;v.y=t*v.y;
 69     return p+v;
 70 }
 71 
 72 
 73 
 74 int n,m,id,x,y;
 75 int v[60];
 76 point p1[100],p2[100];//p1为city  p2为电台 
 77 point qiujiaodian(point touying,point shit)
 78 {
 79     int i;
 80     point ans=p1[y]+(p1[y]-p1[x]),xx;//ans用来更新投影 
 81     xx=p1[y]-p1[x];//线段的方向向量 
 82     for(i=1;i<=m;i++)
 83     {
 84         if(v[i])continue;
 85         point u=shit-p2[i],w,qq;
 86         if(dcmp(u*xx)==0)continue; 
 87         qq=(shit+p2[i])|(0.5);
 88         w.x=u.y,w.y=-u.x;
 89         point jiao;
 90         if(dcmp((qq-p1[x])^xx)==0)jiao=qq;
 91         else
 92             jiao=getjiaodian(qq,w,touying,xx);
 93         if(dcmp(len(touying-ans)-len(jiao-touying)-len(jiao-ans))==0)
 94         {
 95                 ans=jiao; 
 96                 id=i;
 97         }                        
 98     }
 99     return ans;
100 }
101 
102 int main()  
103 {     
104     int i,k;   
105    
106     while(~scanf("%d%d",&n,&m))
107     {
108          for(i=1;i<=n;i++)p1[i].input();
109         for(i=1;i<=m;i++)p2[i].input(); 
110           scanf("%d",&k);
111           while(k--)
112           {
113               scanf("%d%d",&x,&y);
114               int ss,ee;//ss为距离x最近的点,ee为距离b最近的点!! 
115               ss=ee=0;
116               double min1,min2;
117               min1=min2=oo;
118               for(i=1;i<=m;i++)
119               {
120                   if(len(p2[i]-p1[x])<min1)
121                   {
122                       min1=len(p2[i]-p1[x]);
123                       ss=i;
124                   }
125                   if(len(p2[i]-p1[y])<min2)
126                   {
127                       min2=len(p2[i]-p1[y]);
128                       ee=i;
129                   }
130               }
131               if(ss==ee){printf("0\n");continue;}
132               memset(v,0,sizeof(v));
133               v[ss]=1;//v[ee]=1;
134               point shit=p2[ss],touying=p1[x];
135               int cnt=0;
136             while(dcmp(len(p1[x]-p1[y])-len(p1[x]-touying)-len(p1[y]-touying))==0)
137             {
138                 touying=qiujiaodian(touying,shit);
139                 v[id]=1;
140                 shit=p2[id];
141                 cnt++;
142             }
143             
144               printf("%d\n",cnt-1);
145           }
146     }  
147     return 0;  
148 }  
View Code

 

 
 
 
 
 
 
 
 
 
 
 
·
posted @ 2013-08-07 19:15  朱群喜_QQ囍_海疯习习  阅读(201)  评论(0编辑  收藏  举报
Map