hdoj4643GSM【计算几何+二分思想】



GSM

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


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.
 

题意:给出线段a,b和一些点从a走到b当与这些点中的最短距离的点交换记一次问有多少次交换;

思路二分逐步分解这段距离递归求解;

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define eps 1e-7
using namespace std;
struct point{
	double x,y;
}A[55],B[55];
int n,m;
double dist(point a,point b){
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);//能不用sqrt尽量不用用了超时
}
double min_dist(point p){//寻找距离最近的点
	int pos=1,i;
	double Min=dist(p,B[1]);
	for(i=2;i<=m;++i){
		if(Min>dist(p,B[i])){
			Min=dist(p,B[i]);
			pos=i;
		}
	}
	return pos;
}
int slove(point p1,point p2){
	int a=min_dist(p1);
	int b=min_dist(p2);
	if(a==b)return 0;
	if(dist(p1,p2)<eps)return 1;//当两点重合返回考虑有且仅有一次
	point temp;
	temp.x=(p1.x+p2.x)/2.0;
	temp.y=(p1.y+p2.y)/2.0;
	return slove(p1,temp)+slove(temp,p2);
}
int main()
{
	int i,j,k;
	while(scanf("%d%d",&n,&m)!=EOF){
		for(i=1;i<=n;++i){
			scanf("%lf%lf",&A[i].x,&A[i].y);
		}
		for(i=1;i<=m;++i){
			scanf("%lf%lf",&B[i].x,&B[i].y);
		}
		scanf("%d",&k);
		for(i=0;i<k;++i){
			int a,b;
			scanf("%d%d",&a,&b);
			printf("%d\n",slove(A[a],A[b]));
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值