C 为什么spoj给出了错误的答案;整数的幂;?
我正在努力解决spoj上的问题。我的方法很简单。它首先计算从2到63的所有幂的x(x^i=n)。然后,它删除所有的副本,然后最后加起来的权力。但它在spoj上给了我错误的答案。 我在Ideone和我的机器上试过很多用例,但它给了我正确的结果C 为什么spoj给出了错误的答案;整数的幂;?,c,algorithm,C,Algorithm,我正在努力解决spoj上的问题。我的方法很简单。它首先计算从2到63的所有幂的x(x^i=n)。然后,它删除所有的副本,然后最后加起来的权力。但它在spoj上给了我错误的答案。 我在Ideone和我的机器上试过很多用例,但它给了我正确的结果 #include<stdio.h> #include<math.h> int main() { unsigned long long int a,b,result; unsigned long long int pow
#include<stdio.h>
#include<math.h>
int main()
{
unsigned long long int a,b,result;
unsigned long long int power[65],temp;
int i,j;
while(1)
{
scanf("%lld",&a);
scanf("%lld",&b);
if(a==0)
break;
result=0;
power[0]=0;
power[1]=b-a+1;
a--;
for(i=2;i<64;i++)
{
power[i]=floor(pow((long double)b,(long double)1/i));
while(pow((power[i]-1),(long double)i)>=b)
{
power[i]--;
}
while(pow((power[i]+1),(long double)i)<=b)
{
power[i]++;
}
temp=floor(pow((long double)a,(long double)1/i));
while(pow((temp-1),(long double)i)>=a)
{
temp--;
}
while(pow((temp+1),(long double)i)<=a)
{
temp++;
}
power[i]-=temp;
}
for(i=63;i>=1;i--)
{
for(j=i*2;j<64;j=j+i)
{
power[i]-=power[j];
}
}
for(i=1;i<64;i++)
{
result+=i*power[i];
}
printf("%lld\n",result);
}
return 0;
}
#包括
#包括
int main()
{
无符号长整型a,b,结果;
无符号长整型幂[65],温度;
int i,j;
而(1)
{
scanf(“%lld”、&a);
scanf(“%lld”、&b);
如果(a==0)
打破
结果=0;
幂[0]=0;
功率[1]=b-a+1;
a——;
对于(i=2;i=b)
{
权力(i);;
}
而(功率((功率[i]+1),(长双)i)=a)
{
温度--;
}
而(功率((温度+1),(长双精度)i)=1;i--)
{
对于输入(j=i*2;j)
100 100
10000 100000000
100000000000 100000000000
100000000000000 100000000000000
1000000000000000 1000000000000000
0 0
您的输出是
2
100001508
11
14
11
2
100001508
11
14
15
但正确的输出是错误的
2
100001508
11
14
11
2
100001508
11
14
15
现在查找a
的kth
根。做一些数学题
let x = a ^ (1 / k) (^ denotes power NOT XOR)(this is also `kth` root of `a`)
两边取自然对数(ln)
ln x = ln (a ^ (1 / k)) = (1 / k) * ln (a) {property of log}
exp (ln x) = exp (ln (a) / k)
现在两边都取指数
ln x = ln (a ^ (1 / k)) = (1 / k) * ln (a) {property of log}
exp (ln x) = exp (ln (a) / k)
并根据log
属性
exp (ln x) = x
所以我们终于得到了
x = exp (ln(a) / k) which is equivalent to `kth` root of `a`
下面是一个在C
double kth_root_finder(long long int a, long long int k) {
if (k == 1) {
return a;
}
if (k == 2) {
return sqrt(a);
}
return exp(log(a) / k);
}
记住,在数学中,我们使用ln
来寻找自然对数,它与C
中的log
的自然对数相等
double kth_root_finder(long long int a, long long int k) {
if (k == 1) {
return a;
}
if (k == 2) {
return sqrt(a);
}
return exp(log(a) / k);
}
<>强>编辑1 < /强>:-OP指出,将有溢出,但我不认为它会发生。考虑一个例子,我们有< /P>
a = 1000000000000000000 and k = 2 (worst case)(ignoring second if condition)
然后
是上面的一个链接。。
因此,我不认为有机会出现溢出
。如果有,请指出..您是否阅读了有关挑战的任何评论?请阅读@Deduplicator我也阅读了,但我认为我可以使用它一次来计算根。但非常感谢您提供了这个有用的链接。这是否意味着我必须计算第n根myself?如果是的话,你能给我一个链接吗?@deviantfan我看了一下。但是我编辑了我当前的代码来纠正精度错误,但它仍然给了我错误的答案。是因为它充满了我的新更改吗?你能看一下编辑过的代码吗?@Naman:你因为使用了f而失去了精度浮动点算法。这个挑战可能需要您实现某种自定义的任意大小算法(“大数”算法)。我认为这种方法也会带来精度误差。我应该使用最接近的整数或下限作为此函数的输出吗?最后我得到了AC。我使用相同的pow函数获得根的第一个估计值,然后使用INT64计算更正精度误差。之前我没有检查溢出。因此,现在我的解决方案使用首先进行双重计算,然后进行INT64计算。非常感谢您的帮助。@Naman:-恭喜..如果它帮助您接受它..我认为它不会溢出我已经编辑了我的答案..我没有发现溢出的情况..如果您发现任何溢出,请指出