2 ^ 15 = 32768,其数字之和为3 + 2 + 7 + 6 + 8 = 26。 数字2 ^ 1000的数字总和是多少?
我想解决项目欧拉问题16号。我试图在阵列中保存2的功能。假设2 ^ 6 = 128
。然后
int arr[1000];
arr[0] = 1 // or 8 (In other way also)
arr[1] = 2
arr[2] = 8 // or 1
// and so on....
但现在的问题是如何解决这个问题。
我在将数字移动到下一个数组位置时遇到问题。 现在假设,
arr[0] = 8;
在下一次迭代中
arr[0] = 1; and array[1] = 6;
此处arr[0]
包含1,arr[1]
包含6。
下一步
arr[0] = 3;
arr[1] = 2;
....
....
//2 ^ 6
arr[0] = 1;
arr[1] = 2;
arr[2] = 8;
...
...
//2 ^ 10
arr[0] = 1;
arr[1] = 0;
arr[2] = 2;
arr[3] = 4;
.....
.....
等等。请帮帮我。
答案 0 :(得分:7)
你应该检查每个数字,从最不重要的数字开始,加倍并加上前一个数字的进位,将结果模10存储为新的数字值,如果结果超过9,则设置进位为1,否则将其设置为0(或者只将结果的整数除以10):
carry = 0
for i = 0 to MAX_DIGITS-1:
tmp = 2 * digits[i] + carry
digits[i] = tmp % 10
carry = tmp / 10
(这是伪代码 - 将其翻译为C供您自己使用)
正如旁注所示,计算2^1000
在二进制文件中非常容易 - 只有1
后跟1000 0
。将结果转换为十进制表示有点棘手,但存在有效的二进制到BCD转换方法。但我仍然建议您使用GNU MP库。使用GNU MP计算2 ^ 1000只需要6行(#define
行,并且不计算所有空白行):
#include <gmp.h>
#define MAX_DIGITS 302
mpz_t bignum;
char str[MAX_DIGITS+2];
mpz_init2(bignum, 1001);
mpz_ui_pow_ui(bignum, 2, 1000); // set the integer object to 2^1000
mpz_get_str(str, 10, bignum); // convert to base 10
请注意,2^1000
是1001个二进制数字,大约302个(等于1001 * log(2))个十进制数字。为NULL
所需的可能符号字符和mpz_get_str()
终结符添加两个字符。
现在你只需要查看str
中的结果数字,将它们转换为整数并将它们全部加起来。
答案 1 :(得分:1)
#include <stdio.h>
void mul2(int *n){
int c = 0, v;
while(*n>=0){
v = c + *n * 2;
c = v / 10;
*n++ = v % 10;
}
if(c) *n++ = c;//1
*n = -1;//stopper
}
int sum(int *n){
int sum=0;
while(*n>=0)
sum += *n++;
return sum;
}
int main(void){
int arr[1000] = {1, -1};//need 302 + 1, -1 is stoper
int i;
for(i=0;i<1000;i++)
mul2(arr);
printf("%d\n", sum(arr));
return 0;
}
答案 2 :(得分:1)
#include <stdio.h>
#define POWER 1000
int digits[(POWER * 302 + 999)/1000] = {1}; // > log10(2 ** POWER)
int ndigits = 1;
int main(void)
{
for (int i = 0; i < POWER; i++)
for (int n = 0, j = 0;; j++)
{
n += digits[j] * 2;
digits[j] = n % 10;
n /= 10;
if (j == ndigits - 1)
{
if (!n) break;
ndigits++;
}
}
int sum = 0;
for (int i = 0; i < ndigits; i++)
sum += digits[i];
printf("%d\n", sum);
return 0;
}
编辑:一个可能更快但更模糊的内部块:
n += digits[j] * 2;
if (n >= 10)
{
digits[j] = n - 10;
n = 1;
if (j == ndigits - 1)
ndigits++;
}
else
{
digits[j] = n;
if (j == ndigits - 1)
break;
n = 0;
}
答案 3 :(得分:1)
这是我的Python代码:
b = 2**1000
c = str(b)
d = [ ]
for dig in c :
d.append(int(dig))
e = sum(d)
print e
答案 4 :(得分:0)
//Finally I did it.
#include <stdio.h>
#include <stdlib.h>
//2 ^ 1000
int main()
{
int array[1000] = { 0 };
array[0] = 1;
int i, j, cnt, div, carry, temp, sum;
for(i = 0, cnt = 1; i < 1000; i++)
{
div = carry = 0;
for(j = 0; j < 1000; j++)
{
if(carry != 0)
{
array[j] = (array[j] * 2) + carry;
div = array[j] % 10;
temp = array[j] / 10;
array[j] = div ;//+ carry;
carry = temp;
//array[j] = (array[j] * 2) + 1;
//carry = 0;
}
else
{
array[j] = array[j] * 2;
if (array[j] > 9)
{
div = array[j] % 10;
carry = array[j] / 10;
array[j] = div;
}
}
}
}
sum = temp = 0;
printf("The value of 2 ^ 1000 is : ");
for(i = 999; i >= 0; i--)
{
if(array[i] || (temp))
{
temp++;
sum = sum + array[i];
printf("%d", array[i]);
}
}
printf("\nThe sum is : %d \n", sum);
printf("\nThe number of digits are : %d \n", temp);
return 0;
}
答案 5 :(得分:0)
这是我的代码
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int a[10000]={0};
int m=1;
int carry=0;
a[0]=1;
long long int sum=0;
for(int i=1;i<=1000;i++)
{
for(int j=0;j<m;j++)
{
int x=a[j]*2+carry;
a[j]=x%10;
carry=x/10;
}
while(carry!=0)
{
a[m++]=carry%10;
carry/=10;
}
}
for(int i=m-1;i>=0;i--)
sum+=a[i];
printf("%lld",sum);
return 0;
}
答案 6 :(得分:0)
答案 7 :(得分:0)
在这个问题上,我们可以从先前数字的计算中受益。
例如,要计算pow(2,1000)
,我们可以使用pow(2,999)
的数字,
我们可以将前一个数字存储在队列中。当前数字可以通过将前一个数字乘以2乘以一来获得。
在下面的代码中,使用了以上方法:
using namespace std;
#include<bits/stdc++.h>
int main() {
queue<int> q;
q.push(2);
queue<int> q2;
for (int i = 2; i <= 1000;i++) {
int carry = 0;
while (!q.empty())
{
int first = q.front();
q.pop();
int digit = (first * 2 + carry) % 10;
carry = (first*2) / 10;
q2.push(digit);
}
if(carry!=0) {
q2.push(carry);
}
swap(q, q2);
}
int sum = 0;
while(!q.empty()) {
sum += q.front();
q.pop();
}
cout << sum << endl;
}