C++ 我的二进制搜索应用程序不在这里吗?
所以,我在解决这个问题: 一个奇妙的发现即将在生物学领域发生,你是这个研究团队的一员。这项研究是关于测量细胞在无氧和有毒物质环境中的生长情况。研究小组得出了一个可靠的假设,分析数据告诉他们:生长、天数和毒性;由以下公式关联: p=N*NcN 其中p是以数千个细胞为单位测量的生长 N是经过的天数 c是与实验毒性水平相关的常数 当这些细胞达到特定生长时,你的生物学伙伴需要从细胞中取出一些组织。他们要求你写一个程序,告诉他们这将发生的确切时间,给定毒性水平和所需的生长 输入 第一行是T(1≤ T≤ 40000),测试用例的数量,然后是T测试用例 每个测试用例都是一行,有两个整数(pc)由空格分隔 p(1≤ P≤ 1015) c(1≤ c≤ (五) 输出 对于每个测试用例,您必须以十进制格式输出预期时间 我所做的是使用二进制搜索查找天数,如下所示:C++ 我的二进制搜索应用程序不在这里吗?,c++,algorithm,binary-search,C++,Algorithm,Binary Search,所以,我在解决这个问题: 一个奇妙的发现即将在生物学领域发生,你是这个研究团队的一员。这项研究是关于测量细胞在无氧和有毒物质环境中的生长情况。研究小组得出了一个可靠的假设,分析数据告诉他们:生长、天数和毒性;由以下公式关联: p=N*NcN 其中p是以数千个细胞为单位测量的生长 N是经过的天数 c是与实验毒性水平相关的常数 当这些细胞达到特定生长时,你的生物学伙伴需要从细胞中取出一些组织。他们要求你写一个程序,告诉他们这将发生的确切时间,给定毒性水平和所需的生长 输入 第一行是T(1≤ T≤ 4
#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
wherefunc(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
wherefunc(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;
}
}