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 }
·