C++ 我的二进制搜索应用程序不在这里吗?

C++ 我的二进制搜索应用程序不在这里吗?,c++,algorithm,binary-search,C++,Algorithm,Binary Search,所以,我在解决这个问题: 一个奇妙的发现即将在生物学领域发生,你是这个研究团队的一员。这项研究是关于测量细胞在无氧和有毒物质环境中的生长情况。研究小组得出了一个可靠的假设,分析数据告诉他们:生长、天数和毒性;由以下公式关联: p=N*NcN 其中p是以数千个细胞为单位测量的生长 N是经过的天数 c是与实验毒性水平相关的常数 当这些细胞达到特定生长时,你的生物学伙伴需要从细胞中取出一些组织。他们要求你写一个程序,告诉他们这将发生的确切时间,给定毒性水平和所需的生长 输入 第一行是T(1≤ T≤ 4

所以,我在解决这个问题:

一个奇妙的发现即将在生物学领域发生,你是这个研究团队的一员。这项研究是关于测量细胞在无氧和有毒物质环境中的生长情况。研究小组得出了一个可靠的假设,分析数据告诉他们:生长、天数和毒性;由以下公式关联:

p=N*NcN

其中p是以数千个细胞为单位测量的生长

N是经过的天数

c是与实验毒性水平相关的常数

当这些细胞达到特定生长时,你的生物学伙伴需要从细胞中取出一些组织。他们要求你写一个程序,告诉他们这将发生的确切时间,给定毒性水平和所需的生长

输入

第一行是T(1≤ T≤ 40000),测试用例的数量,然后是T测试用例

每个测试用例都是一行,有两个整数(pc)由空格分隔

p(1≤ P≤ 1015)

c(1≤ c≤ (五)

输出

对于每个测试用例,您必须以十进制格式输出预期时间

我所做的是使用二进制搜索查找天数,如下所示:

#define eps 1e-7
const double cont = 14.0;
double p,c;
double binary (double start, double end);
double func (double n);
int main (void)
{
    int t;
    cin>>t;
    while (t != 0)
    {
        cin>>p>>c;
        double mid,ans,start=0,end=cont;
        ans = binary(start,end);
        cout.precision(6);
        cout<<fixed<<ans<<"\n";         
        t--;
    }
    return 0;
}

double func (double n)
{
    double ret = n*pow(n,c*n);
    return ret;
}

double binary (double start, double end)
{
    if (start <= end)
    {
        double mid = start + (end-start)/2.0;
        if (func(mid)-p <= eps)
            return mid;
        else if (func(mid)-p > eps)
            return binary(start,mid);
        else
            return binary(mid,end);
    }
}
附言:我没有张贴图书馆和所有的东西,以避免混乱。此外,一旦得到正确的值,我会将其设置为小数点后6位。我只是想知道,是我的逻辑不正确还是我的二进制搜索执行不正确

编辑:我提交的新代码

double binary (double start, double end)
    {
        if (start <= end)
        {
            double mid = start + (end-start)/2.0;
            double delta = func(mid) - p;
            if (delta < -1*eps)
                return binary(mid,end);
            else if (delta > eps)
                return binary(start,mid);
            else
                return mid;
        }
    }
双二进制(双开始,双结束)
{
如果(启动eps)
返回二进制(开始,中间);
其他的
中途返回;
}
}

您的测试顺序不合理:

if (func(mid)-p <= eps)
    return mid;
else if (func(mid)-p > eps)
    return binary(start,mid);
else
    return binary(mid,end);

牛顿搜索可能比这更快。

您正在按不合理的顺序进行测试:

if (func(mid)-p <= eps)
    return mid;
else if (func(mid)-p > eps)
    return binary(start,mid);
else
    return binary(mid,end);

牛顿搜索可能比这更快。

除了JSF解释的搜索问题之外,您的计算方式也比您需要的更精确

您需要精度为10^-6的
N
。在您的实现中,您一直在搜索,直到找到精度为10^-7的
P
的值。由于函数是指数函数,因此非常陡峭,即
P
随着
N
的变化非常快,这将导致计算量远远超过需要

相反,您应该有一个停止条件
end-start<1e-6

现在我有一个语义问题:10^-6的准确度是否意味着所有数字都必须是正确的,或者最后一个数字是否允许被关闭1?如果允许,停止后,
start
end
将是一个很好的答案。如果没有,可以向上舍入到最接近的10^-6。您应该四舍五入,因为该语句可能要求第一个
N
where
func(N)>P
,而不是等式的近似值。然后,如果它们不同,检查
start
的舍入值是否满足该语句。如果是,则输出该值;如果不是,则输出
end
的舍入值


给定14.0的上限,搜索空间仅为
14.0/1e-6=1.4*10^8
元素。基本的2个日志刚好超过27,因此每个测试用例只需要28次迭代(如果计算更精确的上限,可能需要27次)。这当然不需要复杂的优化就可以通过。

除了JSF解释的搜索问题之外,您的计算方法也比您需要的更精确

您需要精度为10^-6的
N
。在您的实现中,您一直在搜索,直到找到精度为10^-7的
P
的值。由于函数是指数函数,因此非常陡峭,即
P
随着
N
的变化非常快,这将导致计算量远远超过需要

相反,您应该有一个停止条件
end-start<1e-6

现在我有一个语义问题:10^-6的准确度是否意味着所有数字都必须是正确的,或者最后一个数字是否允许被关闭1?如果允许,停止后,
start
end
将是一个很好的答案。如果没有,可以向上舍入到最接近的10^-6。您应该四舍五入,因为该语句可能要求第一个
N
where
func(N)>P
,而不是等式的近似值。然后,如果它们不同,检查
start
的舍入值是否满足该语句。如果是,则输出该值;如果不是,则输出
end
的舍入值


给定14.0的上限,搜索空间仅为
14.0/1e-6=1.4*10^8
元素。基本的2个日志刚好超过27,因此每个测试用例只需要28次迭代(如果计算更精确的上限,可能需要27次)。这绝对不需要复杂的优化才能通过。

这个if语句看起来可疑<代码>如果(函数(mid)-p你的mid完全依赖于开始值和结束值,这就是你要返回的值。如果你从1开始到14,然后把它分成两半,那么你怎么期望它是1呢?那么0--14,0--7,0--3.5,0--1.75…0--875。你确定mid是你想要的吗?@Meghaa,但是在二进制搜索中,我们总是能找到mid值并将其与之比较。在这种情况下是否应该有所不同?我认为这不是关于二进制搜索…而是关于你希望你的代码做什么…你想知道
if (func(mid)-p < -eps)
    return binary(mid,end);
else if (func(mid)-p > eps)
    return binary(start,mid);
else
    return mid;
double binary (double start, double end)
{
    for (;;)
    {
        double mid = (start + end) * .5;
        double delta=func(mid)-p;

        if ( delta < -eps)
            start = mid;
        else if (delta > eps)
            end = mid;
        else
            return mid;
    }
}