나는 comingstorm의 해법에 대한 대수를 적절히 수행하여 구현했습니다. 내 컴퓨터에서 Newton의 방법은 4의 인수로 이진 검색보다 높습니다. 모든 음이 아닌 32 비트 정수에 newton()
을 테스트했습니다.
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
static int newton(double a) {
if (a < 2.0 * log10(2.0)) {
return 1;
} else if (a < 3.0 * log10(3.0)) {
return 2;
}
double a_log_10 = a * log(10);
double x = a/log10(a);
x = (x + a_log_10)/(1.0 + log(x));
x = (x + a_log_10)/(1.0 + log(x));
double n = floor(x);
if (n * log10(n) > a) {
n--;
} else if ((n + 1.0) * log10(n + 1.0) <= a) {
n++;
}
return n;
}
static int binarysearch(double a) {
double l = floor(a/log10(a));
double u = floor(a) + 1.0;
while (1) {
double m = floor((l + u)/2.0);
if (m == l) break;
if (m * log10(m) > a) {
u = m;
} else {
l = m;
}
}
return l;
}
static void benchmark(const char *name, int (*solve)(double)) {
clock_t start = clock();
for (int a = 1 << 22; a >= 10; a--) {
int n = solve(a);
assert(n * log10(n) <= a);
assert((n + 1) * log10(n + 1) > a);
}
printf("%s: %.2f\n", name, (clock() - start)/(double)CLOCKS_PER_SEC);
}
int main(int argc, char *argv[]) {
benchmark("newton", newton);
benchmark("binarysearch", binarysearch);
}
원본 문제에 대해 Netwon 반복 작업을 수행 할 수도 있습니다. 'n + = (a-n * log (n))/(log n + log e)'이면 단계는'd (n log n)/dn = – comingstorm