项目欧拉没有。 16

时间:2012-06-19 13:50:08

标签: c

  

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;
.....
.....

等等。请帮帮我。

8 个答案:

答案 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;
}