这个博客写的还不错
大概是打算清理一下基础算法的知识盲区吧,就去过了一遍
平面最近点对问题刷题以来一共遇到两次。。。可能我数学题写少了
Quoit Design ZOJ - 2107
这大概是一个模板入门题吧
注意的是要你输出半径,所以你求出最近点对距离后还要除于2
struct node{
double x,y;
}point[maxn];
int cup[maxn];
bool cmpx(node a,node b){
if(a.x==b.x){
return a.y<b.y;
}else{
return a.x<b.x;
}
}
bool cmpy(int a,int b){
if(point[a].y==point[b].y){
return point[a].x<point[b].x;
}else{
return point[a].y<point[b].y;
}
}
double get_dis(int a,int b){
return sqrt(pow(point[a].x-point[b].x,2)+pow(point[a].y-point[b].y,2));
}
double closest_pair(int l,int r){
if(r==l+1){
return get_dis(l,r);
}else if(r==l){
return inf*1.0;
}else if(r==l+2){
return min(get_dis(l,r),min(get_dis(l,l+1),get_dis(l+1,r)));
}
int mid=l+r>>1;
double ans=min(closest_pair(l,mid),closest_pair(mid+1,r));
int num=0;
rep(i,l,r){
if(point[i].x>=point[mid].x-ans&&point[i].x<=point[mid].x+ans){
cup[++num]=i;
}
}
sort(cup+1,cup+num+1,cmpy);
rep(i,1,num){
rep(j,i+1,num){
if(point[cup[j]].y-point[cup[i]].y>=ans){
break;
}
ans=min(ans,get_dis(cup[i],cup[j]));
}
}
return ans;
}
void solve(){
int n;while(~scanf("%d",&n)&&n){
rep(i,1,n){
scanf("%lf %lf",&point[i].x,&point[i].y);
}
sort(point+1,point+n+1,cmpx);
printf("%.2f\n",closest_pair(1,n)/2);
}
}
Raid POJ - 3714
这个题不同的地方是每个人要到指定的地方,求出哪个人可以最快到达一个地方(也就是求哪个人到炮台最近,有很多炮台)
给人和炮台标记不同的记号我想到了,但我却一直在想怎么在搜距离时区分开。。。后来发现我直接修改dis函数就好了 对于记号相同的直接记作无穷大距离就好了…
struct node{
double x,y;
int id;
}point[maxn];
int cup[maxn];
bool cmpx(node a,node b){
if(a.x==b.x){
return a.y<b.y;
}else{
return a.x<b.x;
}
}
bool cmpy(int a,int b){
if(point[a].y==point[b].y){
return point[a].x<point[b].x;
}else{
return point[a].y<point[b].y;
}
}
double get_dis(int a,int b){
return point[a].id==point[b].id ? 5e11 : sqrt(pow(point[a].x-point[b].x,2)+pow(point[a].y-point[b].y,2));
}
double closest_pair(int l,int r){
if(r==l+1){
return get_dis(l,r);
}else if(r==l){
return 1.0*5e11;
}else if(r==l+2){
return min(get_dis(l,r),min(get_dis(l,l+1),get_dis(l+1,r)));
}
int mid=l+r>>1;
double ans=min(closest_pair(l,mid),closest_pair(mid+1,r));
int num=0;
rep(i,l,r){
if(point[i].x>=point[mid].x-ans&&point[i].x<=point[mid].x+ans){
cup[++num]=i;
}
}
sort(cup+1,cup+num+1,cmpy);
rep(i,1,num){
rep(j,i+1,num){
if(point[cup[j]].y-point[cup[i]].y>=ans){
break;
}
ans=min(ans,get_dis(cup[i],cup[j]));
}
}
//de(l),de(r),de(ans),de("pppppppppp");
return ans;
}
void solve(){
int n=read();
rep(i,1,n){
scanf("%lf %lf",&point[i].x,&point[i].y);
point[i].id=-1;
}
rep(i,n+1,2*n){
scanf("%lf %lf",&point[i].x,&point[i].y);
point[i].id=1;
}
sort(point+1,point+n*2+1,cmpx);
printf("%.3f\n",closest_pair(1,n*2));
}