这道题题意就是:在一个笛卡尔坐标系中,n个点(点数不超过十万!)分布不一,在这n个点之中,求出相距最短的两个点之间的距离!
思路:这个题思路很简单,就是枚举并比较对吧?然后自然而然就想到使用暴力方法来解,但是因为最多有10万个点,时间复杂度是o(n*n);所以结果自然就是超时咯!
这个题有很多大牛使用的分治,二分,在这里我没有使用。上网看了一下大牛们高深的解题报告,然后发现了一个东西!——就是要把n个点x坐标和y坐标进行排序,然后进行比较!——这样一来再比较所用的时间就要少得多了!
代码如下:
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const double inf=5201314; struct Point//定义点的结构体! { double x,y; } point[201314]; double ans=inf; int cmp(Point a,Point b) {//排序条件!默认是按x从小到大进行排序!不然就按照y从小到大排序! if(a.x==b.x) return a.y<b.y; return a.x<b.x; } double getdis(Point a,Point b) { double ki=a.x-b.x; double ll=a.y-b.y; return sqrt(ki*ki+ll*ll);//计算出两点之间的距离! } double now_min(int begin,int num) { double min=inf; for(int i=begin+1; i<num; i++) { double dis=getdis(point[begin],point[i]); if(min>dis) min=dis; else break;//因为我之前已经排好序了, //所以肯定第i个点与它后面的点的距离是越来越大的,所以else就可以直接退出了! } return min; } int main() { int num;//表示点de数mu! while(scanf("%d",&num)!=EOF) { if(!num)break; for(int i=0; i<num; i++) scanf("%lf%lf",&point[i].x,&point[i].y); sort(point,point+num,cmp);//按x值从小到大进行排序! ans=inf; for(int i=0; i<num-1; i++) ans=ans<now_min(i,num)?ans:now_min(i,num);//一个简单的比较! printf("%.2lf\n",ans/2); } return 0; }
原文地址:http://blog.csdn.net/u014004096/article/details/40858873