距离上次写算法题目已经有半个月了吧。从20号回学校参加毕业典礼,和舍友,和同学疯狂了十天。很高兴,也很伤感。终于,我也本科毕业了。最终,分离的那一天还是要到来
的,我最舍不得的是和海哥还有小强的感情,再也听不到他们的嬉戏打闹的声音,再也听不到他们的狂叫,再也看不到他们疯疯癫癫的样子。现在回想起我们一起的点点滴滴,我的眼泪又忍不住要往下滴了。在这我只想偷偷的告诉你们,我想你们了。
现在我们都开始了自己新的生活了,虽然说我们不能活在过去,但是我们也要相离莫相忘。一定要彼此挂念!
题目描述:
给定平面N个点的坐标,找出距离最近的点对以及最近的距离。
解题思路:
用分治的方法来解决。按x轴排序,然后找中间的点, 把所有点分成左右两部分,递归求左右两边的最短距离。当然还要考虑左边和右边点的距离。
好了,关于问题的描述网上有很多很多,我也懒得写了,也写不了那么好。我也是先看了别人的分析,才写出来的。
代码:
//求平面内最近的两点及距离 #include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct{ int x; int y; }POINT; //记录最近点对以及距离 typedef struct{ int a; int b; double dMinDist; }MinestPoint; POINT pointAll[100]; POINT pointY[100]; MinestPoint nMinestPoint; MinestPoint Min(MinestPoint a, MinestPoint b) { if (a.dMinDist < b.dMinDist) return a; else return b; } //按x轴排序 int cmpX(const void *a, const void *b) { POINT *p1,*p2; p1 = (POINT *)a; p2 = (POINT *)b; if (p1->x == p2->x) return p1->y - p2->y; return p1->x - p2->x; } //按y轴排序 int cmpY(const void *a, const void *b) { POINT *p1,*p2; p1 = (POINT *)a; p2 = (POINT *)b; if (p1->y == p2->y) return p1->x - p2->x; return p1->y - p2->y; } int Input() { int i=0,n; FILE *fp; fp = fopen("in.txt","r"); if (fp == NULL) { printf("fopen error.\n"); return -1; } fscanf(fp,"%d",&n); while (i < n) { fscanf(fp,"%d%d",&pointAll[i].x,&pointAll[i].y); i++; } qsort(pointAll,n,sizeof(POINT),cmpX); for (i = 0; i < n; i++) { printf("(%d,%d) ",pointAll[i].x,pointAll[i].y); } printf("\n"); return n; } double Dist(POINT a, POINT b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } MinestPoint DivideConque(int left, int right) { int nMid,nCnt,i,j; double nDist; MinestPoint nMinLeft,nMinRight; if (left == right) { if (1000 == nMinestPoint.dMinDist ) { nMinestPoint.a = nMinestPoint.b = left; } return nMinestPoint; } if (left+1 == right) { nDist = Dist(pointAll[left],pointAll[right]); if ( nDist < nMinestPoint.dMinDist) { nMinestPoint.a = left; nMinestPoint.b = right; nMinestPoint.dMinDist = nDist; } return nMinestPoint; } nMid = (right + left)/2; nMinLeft = DivideConque(left,nMid); nMinRight = DivideConque(nMid+1,right); nMinestPoint = Min(nMinLeft,nMinRight); //选取在中线附近的点 nCnt = 0; for (i = left; i <= right; i++) { if (pointAll[i].x <= pointAll[nMid].x + nMinestPoint.dMinDist && pointAll[i].x >= pointAll[nMid].x - nMinestPoint.dMinDist) { pointY[nCnt++] = pointAll[i]; } } qsort(pointY,nCnt,sizeof(POINT),cmpY); for (i = 0; i < nCnt; i++) { for (j = i + 1; j < nCnt; j++) { if (pointY[j].y - pointY[i].y > nMinestPoint.dMinDist) break; nDist = Dist(pointY[i],pointY[j]); if (nDist < nMinestPoint.dMinDist) { nMinestPoint.a = i; nMinestPoint.b = j; nMinestPoint.dMinDist = nDist; } } } return nMinestPoint; } int main() { int n,a,b; nMinestPoint.dMinDist = 1000; //假设1000为正无穷 n = Input(); DivideConque(0,n-1); a = nMinestPoint.a; b = nMinestPoint.b; printf("Minest Dist is:%f.\n",nMinestPoint.dMinDist); printf("the point a:(%d,%d),point b is:(%d,%d).\n",pointAll[a].x,pointAll[a].y, pointAll[b].x,pointAll[b].y); return 0; }
2013/7/7 20:53