#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <sys/time.h> #include <windows.h> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define mem(a,b) memset(a,b,sizeof(a)) #define MAXN 100010 const int T = 1;//循环次数 const int G = 1;//样本组数 struct point { double x,y; }p[MAXN],q[MAXN]; int px[MAXN],py[MAXN],ty[MAXN],n; int cmpx(const point& a,const point& b) { return a.y<b.y; } int cmpy(const int& a,const int& b) { return q[a].y<q[b].y; } double dist(point& a,point& b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } double mindist(int l,int r) { if(r==l+1) return dist(q[l],q[r]); if(l+2==r) return min(dist(q[l],q[r]),min(dist(q[l],q[l+1]),dist(q[l+1],q[r]))); int mid = (l+r)>>1; double ans = min(mindist(l,mid),mindist(mid+1,r)); int i,j,cnt=0; for(i=l;i<=r;i++) { if(p[i].x>=q[mid].x-ans&&q[i].x<=q[mid].x+ans) ty[cnt++]=i; } sort(ty,ty+cnt,cmpy); for(i=0;i<cnt;i++) { for(j=i+1;j<cnt;j++) { if(q[ty[j]].y-q[ty[i]].y>=ans) break; ans=min(ans,dist(q[ty[i]],q[ty[j]])); } } return ans; } void showa() { int i; for(i = 0;i<n;i++) printf("(%.2lf,%.2lf) ",p[i].x,p[i].y); printf(" "); } LL getCurrentTime()//计算算法执行时间 { /* struct timeval tv; gettimeofday(&tv,NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000; */ DWORD start; start = GetTickCount(); //printf("time %d ",start); return start; } int main() { int i,j,k,t; LL t1,t2; double tsum,sum=0; while(~scanf("%d",&n) && n) { printf("数据规模:%d %d组样本时间(ms): ",n,G); srand(unsigned(time(0))); for(j=1;j<=G;j++)//样本组数 { tsum=0; for(i = 0;i<n;i++)//随机点对 { p[i].x = rand()%1000; p[i].y = rand()%1000; } sort(p,p+n,cmpx); //showa(); for(k=0;k<T;k++)//数据小时循环次数 { for(i = 0;i<n;i++) { q[i].x = p[i].x; q[i].y = p[i].y; } //showb(); t1 = getCurrentTime(); mindist(0,n-1); t2 = getCurrentTime(); tsum+=(t2-t1); //showb(); //printf(" "); } //show(); sum+=tsum/T; printf("%lf ",tsum/T); } printf("平均时间: "); printf("%lf ",sum/G); } return 0; }
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <time.h> #include <math.h> #include <windows.h> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define mem(a,b) memset(a,b,sizeof(a)) #define MAXN 100010 const int T = 1;//循环次数 const int G = 5;//样本组数 struct point { double x,y; }p[MAXN],q[MAXN];//保存所有的点坐标 int tmp[MAXN],n; int cmpx(const point& a,const point& b)//用于点的排序 { return a.y<b.y; } int cmpy(const int& a,const int& b) { return q[a].y<q[b].y; } double dist(point& a,point& b)//返回两个点距离的平方 { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } double mindist(int l,int r)//分治法返回所有点对的最小距离,l为左界,r为右界 { double ans,ans1,ans2; int i,j,cnt=0; mem(tmp,0); if(r==l+1) return dist(q[l],q[r]); if(l+2==r) return min(dist(q[l],q[r]),min(dist(q[l],q[l+1]),dist(q[l+1],q[r]))); int mid = (l+r)>>1;//分治 ans1 = mindist(l,mid);//左半边的最小值 ans2 = mindist(mid+1,r);//右半边的最小值 ans = min(ans1,ans2);//取较小那个 for(i=l;i<=r;i++)//分离出宽度为ans的区间 { if(fabs(q[mid].x-q[i].x) <= ans) tmp[cnt++]=i; } sort(tmp,tmp+cnt,cmpy); //线性扫描 for(i=0;i<cnt;i++) { for(j=i+1;j<cnt && q[tmp[j]].y - q[tmp[i]].y < ans;j++) { double d = dist(q[tmp[i]],q[tmp[j]]); ans=min(ans,d); } } return ans; } void showa() { int i; for(i = 0;i<n;i++) printf("(%.2lf,%.2lf) ",p[i].x,p[i].y); printf(" "); } _int64 getCurrentTime()//计算算法执行时间 { /* struct timeval tv; gettimeofday(&tv,NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000; */ DWORD start; start = GetTickCount(); //printf("time %d ",start); return start; } int main() { int i,j,k,t; _int64 t1,t2; double tsum,sum=0,res; while(~scanf("%d",&n) && n) { printf("数据规模:%d %d组样本时间(ms): ",n,G); srand(unsigned(time(0))); sum=0; for(j=1;j<=G;j++)//样本组数 { tsum=0; for(i = 0;i<n;i++)//随机点对 { p[i].x = rand()%10000; p[i].y = rand()%10000; } sort(p,p+n,cmpx); //showa(); for(k=0;k<T;k++)//数据小时循环次数 { for(i = 0;i<n;i++) { q[i].x = p[i].x; q[i].y = p[i].y; } //showb(); t1 = getCurrentTime(); res = mindist(0,n-1); t2 = getCurrentTime(); tsum+=(t2-t1); //showb(); //printf(" "); } //show(); sum+=tsum/T; printf("%.2lf ",tsum/T); } printf(" 平均运行时间: %.2lf ",sum/G); printf("最短距离为: %.2lf ",sqrt(res)); } return 0; }