算法作业二

 

 

#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("\n");
}

LL getCurrentTime()//计算算法执行时间
{
   /*
   struct timeval tv;
   gettimeofday(&tv,NULL);
   return tv.tv_sec * 1000 + tv.tv_usec / 1000;
   */
   DWORD start;
   start = GetTickCount();
   //printf("time %d\n",start);
   return start;
}


int main()
{
    int i,j,k,t;
    LL t1,t2;
    double tsum,sum=0;
    while(~scanf("%d",&n) && n)
    {
        printf("数据规模:%d\n%d组样本时间(ms):\n",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("\n");
            }
            //show();
            sum+=tsum/T;
            printf("%lf\t\n",tsum/T);
        }
        printf("平均时间:\n");
        printf("%lf\t\n",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("\n");
}

_int64 getCurrentTime()//计算算法执行时间
{
   /*
   struct timeval tv;
   gettimeofday(&tv,NULL);
   return tv.tv_sec * 1000 + tv.tv_usec / 1000;
   */
   DWORD start;
   start = GetTickCount();
   //printf("time %d\n",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\n%d组样本时间(ms):\n",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("\n");
            }
            //show();
            sum+=tsum/T;
            printf("%.2lf\t",tsum/T);
        }
        printf("\n平均运行时间: %.2lf\n",sum/G);
        printf("最短距离为: %.2lf\n\n",sqrt(res));
    }

    return 0;
}

 

posted @ 2016-10-24 14:09  qlky  阅读(193)  评论(0编辑  收藏  举报