算法-最近点对问题,我用分治写的,和正确的基本一样为什么我的会超时?杭电1007

问题描述

最近点对问题,我用分治写的,和正确的基本一样为什么我的会超时?杭电1007
高手帮忙看看,已经弄了很长时间了还是看不出来哪里有问题,感觉写得和网上的一样呀。

#include<iostream>#include<cmath>using namespace std;void kuaipai(double* double* int int);double zuijindian(double* double* int int);double x[100000] y[100000] temx[100000] temy[100000];int main(){    int n;    while (cin >> n&&n != 0)    {        for (int i = 0; i<n; i++)        {            cin >> x[i];            cin >> y[i];        }        kuaipai(x y 0 n - 1);        printf(""%.2lfn"" sqrt(zuijindian(x y 0 n - 1)) / 2);    }}void kuaipai(double* x double*y int p int r){    double m = x[r];    double t;    int i = p - 1;    if (p < r)    {        for (int j = p; j < r; j++)        {            if (x[j] < m)            {                i++;                t = x[i];                x[i] = x[j];                x[j] = t;                t = y[i];                y[i] = y[j];                y[j] = t;            }        }        x[r] = x[i + 1];        x[i + 1] = m;        t = y[r];        y[r] = y[i + 1];        y[i + 1] = t;        kuaipai(x y p i);        kuaipai(x y i + 2 r);    }}double zuijindian(double*x double*y int p int r){    int m;    double d d_ t d1 d2;    if (p == r) //如果有一个点    {        return 0;    }    if (r - p == 1)//如果有两个点    {        d = (x[p] - x[r])*(x[p] - x[r]) + (y[p] - y[r])*(y[p] - y[r]);        return d;    }    if (r - p == 2)//如果有三个点    {        d = (x[p] - x[r])*(x[p] - x[r]) + (y[p] - y[r])*(y[p] - y[r]);        d1 = (x[p + 1] - x[r])*(x[p + 1] - x[r]) + (y[p + 1] - y[r])*(y[p + 1] - y[r]);        d2 = (x[p + 1] - x[p])*(x[p + 1] - x[p]) + (y[p + 1] - y[p])*(y[p + 1] - y[p]);        if (d>d1)        {            d = d1;        }        if (d>d2)        {            d = d2;        }        return d;    }    m = (p + r) / 2;//分治    d1 = zuijindian(x y p m);    d2 = zuijindian(x y m + 1 r);    if (d1<d2)    {        d = d1;        d_ = sqrt(d1);    }    else {        d_ = sqrt(d2);        d = d2;    }    int  k = 0;    for (int i = m - 1; i >= 0 && fabs(x[m] - x[i]) <= d_; i--)//接下来两个for搜索分界相邻长度为d_的区域里的点    {        temx[k] = x[i];        temy[k] = y[i];        k++;    }    for (int i = m; i <= r && fabs(x[m] - x[i]) <= d_; i++)    {        temx[k] = x[i];        temy[k] = y[i];        k++;    }    kuaipai(temy temx 0 k - 1);    for (int i = 0; i<k; i++)//比较中间区域的点    {        for (int j = i + 1; j < k&&fabs(temy[j] - temy[i]) < d_; j++)        {            t = (temy[i] - temy[j])* (temy[i] - temy[j]) + (temx[i] - temx[j])*(temx[i] - temx[j]);            if (d>t)            {                d = t;            }        }    }    return d;}
时间: 2025-01-21 09:24:23

算法-最近点对问题,我用分治写的,和正确的基本一样为什么我的会超时?杭电1007的相关文章

既然java语言提供了排序算法的封装,为什么我们还要自己写冒泡

问题描述 既然java语言提供了排序算法的封装,为什么我们还要自己写冒泡 一个关于排序的问题:既然java语言提供了排序算法的封装,为什么我们还要自己写冒泡排序?什么时候用到冒泡排序? 解决方案 目的是为了让你学习,冒泡排序是最容易理解的排序算法. 解决方案二: Java语言写的各种排序算法[未完] 解决方案三: java封装好的是快排吧,首先快排是不稳定排序,只是平均时间复杂度最低而已.简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳.当数据量过大时堆排序的优势又体现

算法-最近点对问题中对坐标排序表示不解。

问题描述 最近点对问题中对坐标排序表示不解. 在看算法导论时,遇到一些算法问题,不是很理解.分治法求最近点对问题中,为什么要依据x和y进行排序? 解决方案 http://blog.csdn.net/dddddz/article/details/13781929

经典算法(4) 直接选择排序及交换二个数据的正确实现

直接选择排序和直接插入排序类似,都将数据分为有序区和无序区,所不同的是直接播放排序是将无序区 的第一个元素直接插入到有序区以形成一个更大的有序区,而直接选择排序是从无序区选一个最小的元素直 接放到有序区的最后. 设数组为a[0-n-1]. 1. 初始时,数组全为无序区为a[0..n-1].令 i=0 2. 在无序区a[i-n-1]中选取一个最小的元素,将其与a[i]交换.交换之后a[0-i]就形成了一个 有序区. 3. i++并重复第二步直到i==n-1.排序完成. 直接选择排序无疑是最容易实现

算法-C/C++杭电1501题Wooden sticks 求挑错

问题描述 C/C++杭电1501题Wooden sticks 求挑错 DescriptionThere is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time called setup

算法 c++-杭电1087,,dp问题,求解答!

问题描述 杭电1087,,dp问题,求解答! #include using namespace std; int n; int a[10005]; int vis[10005]; int dp(int n) { if(vis[n]!=-1) return vis[n]; vis[n] = 0; int i; for(i= n-1;i>=0;i--) { if(i==-1) return 0; dp(i); if(vis[i]>=vis[n]) vis[n] = vis[i]; if(a[i]&

【算法】2 由股票收益问题再看分治算法和递归式

回顾分治算法 分治算法的英文名叫做"divide and conquer",它的意思是将一块领土分解为若干块小部分,然后一块块的占领征服,让它们彼此异化.这就是英国人的军事策略,但我们今天要看的是算法. 如前所述,分治算法有3步,在上一篇中已有介绍,它们对应的英文名分别是:divide.conquer.combine. 接下来我们通过多个小算法来深化对分治算法的理解. 二分查找算法 问题描述:在已排序的数组A中查找是否存在数字n. 1)分:取得数组A中的中间数,并将其与n比较 2)治:

五大常用算法之一:分治算法

分治算法 一.基本概念    在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小 的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立 叶变换(快速傅立叶变换)--     任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n

【万字总结】以插排和分治为例来看如何分析与设计算法

插入排序及其解决思路 算法的作用自然不用多说,无论是在校学生,还是已经工作多年,只要想在计算机这条道路走得更远,算法都是必不可少的. 就像编程语言中的"Hello World!"程序一般,学习算法一开始学的便是排序算法.排序问题在日常生活中也是很常见的,说得专业点: 输入是:n个数的一个序列<a1,a2,...,an−1,an> 输出是:这n个数的一个全新的序列<a,1,a,2,...,a,n−1,a,n>,其特征是a,1≤a,2≤...≤a,n−1≤a,n 举

使用PHP实现二分查找算法代码分享

第一种方法: [二分查找要求]:1.必须采用顺序存储结构 2.必须按关键字大小有序排列. [优缺点]折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表. [算法思想]首先,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表. 复制代码 代码如下: <?