处理n ^ n(1≤n≤10^ 9)的优化方式
我使用了long long int
,但它不够好,因为值可能是(1000 ^ 1000)
搜索并找到GMP library
http://gmplib.org/和BigInt class
,但不想使用它们。 我正在寻找一些处理此问题的数值方法。
我需要打印n^n
的第一个和最后一个 k (1≤k≤9)个数字
对于第一个 k 数字,我得到的如下所示(这有点丑陋的方式)
num = pow(n,n);
while(num){
arr[i++] = num%10;
num /= 10;
digit++;
}
while(digit > 0){
j=digit;
j--;
if(count<k){
printf("%lld",arr[j]);
count++;
}
digit--;
}
以及最后的 k 数字使用num % 10^k
,如下所示。
findk=pow(10,k);
lastDigits = num % findk;
enter code here
k的最大值是9.所以我最多只需要18位数。 我想到的是获得那些18位数而没有真正解决完整的n ^ n表达式。
任何想法/建议??
答案 0 :(得分:5)
// note: Scope of use is limited.
#include <stdio.h>
long long powerMod(long long a, long long d, long long n){
// a ^ d mod n
long long result = 1;
while(d > 0){
if(d & 1)
result = result * a % n;
a = (a * a) % n;
d >>=1;
}
return result;
}
int main(void){
long long result = powerMod(999, 999, 1000000000);//999^999 mod 10^9
printf("%lld\n", result);//499998999
return 0;
}
答案 1 :(得分:4)
查找最不重要的数字(最后的k位数)很容易,因为模块化算术的属性表示:(n*n)%m == (n%m * n%m)%m
,因此BLUEPIXY后跟exponentiation by squaring method显示的代码将找到k
LSD很有效。
现在,N^N
的最重要数字(第1位数字)可以通过这种方式找到:
We know,
N^N = 10^(N log N)
因此,如果您计算N log (N)
,您将得到一些此格式xxxx.yyyy
,现在我们必须使用此数字作为10的幂,很容易理解xxxx或整数部分数字会在10后添加xxxx零,这对你来说并不重要!这意味着,如果您计算10^0.yyyy
,您将获得您正在寻找的那些重要数字。
所以解决方案将是这样的:
double R = N * log10 (N);
R = R - (long long) R; //so taking only the fractional part
double V = pow(10, R);
int powerK = 1;
for (int i=0; i<k; i++) powerK *=10;
V *= powerK;
//Now Print the 1st K digits from V
答案 2 :(得分:0)
为什么不想使用bigint个库?
bignum算法很难正确有效地完成。你仍然可以通过研究这个主题来获得博士学位。
拳头,bigint算术具有非平凡的算法
然后,bigint实现通常需要一些机器指令(比如add with carry),这些指令在普通的C中不易访问。
对于您的具体问题( N N 的第一位和最后几位数字),您最好还在纸上(使用算术定理)来降低复杂性。我不是专家,但我想这仍然是难以处理的,可能复杂性比 O(N)
更糟糕