所以,我正在解决这个问题:http://www.spoj.com/problems/IMMERSED/
一项奇妙的发现即将在生物学领域发生,您也是研究团队的一员。该研究涉及在无氧环境和有毒物质存在的环境中测量细胞生长。该团队得出了一个愚蠢的假设,分析的数据告诉他们:增长,天数和毒性;与此公式有关:
P = N * N cN ;
其中 P 是在数千个细胞中测量的增长。
N 是经过的天数。
和 c 是与实验毒性水平相关的常数。
当这些细胞达到特定的生长时,您的生物合作伙伴需要从细胞中取出一些组织。考虑到毒性水平和所需的增长,他们要求你编写一个程序,告诉他们确切的时间。
输入
第一行是 T (1≤ T ≤40,000),测试用例的数量,然后是 T 测试用例。< / p>
每个测试用例是一个由空格分隔的2个整数( P c )的行。
P (1≤ P ≤10 15 )
c (1≤ c ≤5)
输出
对于每个测试用例,您必须以十进制格式输出预期时间。
我所做的是使用二元搜索来查找天数如下:
#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);
}
}
但是,在运行我的代码时,即使是给定的测试用例,它也会给出错误的答案:
Input:
3
1 1
3 4
100 1
Output:
1.000000
1.207384
3.086308
My output (for the above input)
0.875
0.875
1.75
PS:我没有发布库,所有这些都是为了避免混乱。另外,一旦得到正确的值,我会将其设置为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;
}
}
答案 0 :(得分:4)
您正在以不健全的顺序进行测试:
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 binary(mid,end);
else if (func(mid)-p > eps)
return binary(start,mid);
else
return mid;
我也不确定这两个递归调用。在这种情况下,我保留了你的逻辑(因为我可能误解了你的公式),但他们向后看我。
我确信你应该在内部案例之前测试(并使用递归调用)两个外部案例(func(mid)-p < -eps
和func(mid)-p > eps
)(然后有效{ {1}})
编辑:该二进制搜索的更清晰(更快)版本是:
abs(func(mid)-p) < eps
牛顿搜索可能比这更快。
答案 1 :(得分:2)
除了搜索JSF解释的问题之外,您还可以比您需要的更准确地计算方式。
您需要N
,精确度为10 ^ -6。通过实施,您可以进行搜索,直到找到具有P
的值,精确度为10 ^ -7。由于函数是指数的,因此非常陡峭,即P
与N
的变化非常快,这将导致计算量超出必要的程度。
相反,你应该有一个停止条件end - start < 1e-6
。
现在我有一个语义问题:10 ^ -6的准确度是否意味着所有数字必须正确,或者最后一个数字是否允许关闭1?如果允许,start
或end
在停止后将是一个很好的答案。如果没有,你可以将它们向上舍入到最接近的10 ^ -6。你应该四舍五入,因为该陈述可能要求第一个N
func(N) > P
,而不是相等的近似值。然后,如果它们不同,请检查start
的舍入值是否满足该语句。如果是,则输出,如果不是,则输出舍入值end
。
给定14.0的上限,搜索空间只是14.0 / 1e-6 = 1.4 * 10^8
个元素。它的基数2对数刚好超过27,因此每个测试用例应该只需要28次迭代(如果计算更准确的上限,则可能需要27次)。这绝对不应该要求复杂的优化。