次の質問があります。これは、実際に最近受けたコーディング テストからのものです。
質問:
関数f(n) = a*n + b*n*(floor(log(n)/log(2))) + c*n*n*n
が存在します。
特定の値で、みましょうf(n) = k
。
与えられk, a, b, c
て、見つけますn
。
の指定された値に対してk
、値が存在しないn
場合は 0 を返します。
制限:
1 <= n < 2^63-1
0 < a, b < 100
0 <= c < 100
0 < k < 2^63-1
ここでの論理はf(n)
、与えられた a、b、c に対して純粋に増加しているのでn
、二分探索で見つけることができるということです。
私が書いたコードは次のとおりです。
#include<iostream>
#include<stdlib.h>
#include<math.h>
using namespace std;
unsigned long long logToBase2Floor(unsigned long long n){
return (unsigned long long)(double(log(n))/double(log(2)));
}
#define f(n, a, b, c) (a*n + b*n*(logToBase2Floor(n)) + c*n*n*n)
unsigned long long findNByBinarySearch(unsigned long long k, unsigned long long a, unsigned long long b, unsigned long long c){
unsigned long long low = 1;
unsigned long long high = (unsigned long long)(pow(2, 63)) - 1;
unsigned long long n;
while(low<=high){
n = (low+high)/2;
cout<<"\n\n k= "<<k;
cout<<"\n f(n,a,b,c)= "<<f(n,a,b,c)<<" low = "<<low<<" mid="<<n<<" high = "<<high;
if(f(n,a,b,c) == k)
return n;
else if(f(n,a,b,c) < k)
low = n+1;
else high = n-1;
}
return 0;
}
次に、いくつかのテストケースで試しました:
int main(){
unsigned long long n, a, b, c;
n = (unsigned long long)pow(2,63)-1;
a = 99;
b = 99;
c = 99;
cout<<"\nn="<<n<<" a="<<a<<" b="<<b<<" c="<<c<<" k = "<<f(n, a, b, c);
cout<<"\nANSWER: "<<findNByBinarySearch(f(n, a, b, c), a, b, c)<<endl;
n = 1000;
cout<<"\nn="<<n<<" a="<<a<<" b="<<b<<" c="<<c<<" k = "<<f(n, a, b, c);
cout<<"\nANSWER: "<<findNByBinarySearch(f(n, a, b, c), a, b, c)<<endl;
return 0;
}
その後、奇妙なことが起こりました。
コードはテストケースに対して機能し、n = (unsigned long long)pow(2,63)-1;
n の値を正しく返します。しかし、それはうまくいきませんでしたn=1000
。出力を印刷したところ、次のようになりました。
n=1000 a=99 b=99 c=99 k = 99000990000
k= 99000990000
f(n,a,b,c)= 4611686018427387904 low = 1 mid=4611686018427387904 high = 9223372036854775807
...
...
k= 99000990000
f(n,a,b,c)= 172738215936 low = 1 mid=67108864 high = 134217727
k= 99000990000
f(n,a,b,c)= 86369107968 low = 1 mid=33554432 high = 67108863
k= 99000990000
f(n,a,b,c)= 129553661952 low = 33554433 mid=50331648 high = 67108863**
...
...
k= 99000990000
f(n,a,b,c)= 423215328047139441 low = 37748737 mid=37748737 high = 37748737
ANSWER: 0
数学的に何かが正しくないように見えました。の値がf(1000)
の値より大きいのはf(33554432)
どうしてですか?
そこで、Python で同じコードを試してみたところ、次の値が得られました。
>>> f(1000, 99, 99, 99)
99000990000L
>>> f(33554432, 99, 99, 99)
3740114254432845378355200L
したがって、値は間違いなく大きくなります。
質問:
- 正確に何が起こっているのですか?
- どのように解決すればよいですか?