3

私は友人から尋ねられました:

の場合2^10 = 1024 、1024 を取り、その数字を分割して要約できます。

1+0+2+4 = 7.

かんたんだよ。

ただし、入力が2^30000(入力が実際には長い文字列である"1000...") 場合、この値を保持できる .net 型はありません。

したがって、その桁(10進数の桁)を合計するためのトリックが必要です....

編集:

関連するトリック (見つけるため10^20 - 16)

100 = 10^2 (ゼロが 1 つと 2 つ)

10^20 = (1 と 20 個のゼロ)

したがって:

10^20 - 16 = 18 ナイン、8 と 4。

18*9+8+4 = 174

しかし、私はこの解決策を私の問題に変換することに成功していません.(私はかなり試しました).

* .netライブラリの文字列関数、数学関数を使用できるため、この質問に.netのタグを付けています。*

質問

の結果である多くの数を合計できるトリックはありますx^nか?

ここでのトリックは何ですか?

編集#2:.net2タグ(bigintegerが利用できない場所)を追加しました-bigintegerなしでどうやってそれを行うことができるのだろうか.(私は隠されたトリックを探しています)

4

4 に答える 4

7

これを行うには、 BigInteger構造を利用できます。MSDNに書いてある通り

BigInteger 型は不変型であり、理論的には値に上限または下限がない任意の大きな整数を表します。

基本的に、 BigInteger インスタンスを作成して指数を評価した後、それを文字列に変換できます。その後、その文字列の各文字を繰り返し処理し、各文字を int 数値に変換します。これらすべての int 数値を加算すると、答えが得られます。

BigInteger bi = new BigInteger(2);
var bi2 = BigInteger.Pow(bi, 30000);
BigInteger sum = new BigInteger();
foreach(var ch in bi2.ToString())
    sum = BigInteger.Add(sum, new BigInteger(int.Parse(ch.ToString())));
MessageBox.Show(bi2.ToString() + " - " + sum.ToString());
于 2013-04-27T08:04:14.913 に答える
5

数値の10 進数の合計を見つけるための一般的なトリックはありません。

ただし、数値の基数 10 桁の根を見つけるための簡単なトリックがあります。

あなたが言うように、数字の合計は、単にすべての数字の合計です。1024 の基数 10 桁の合計は 1 + 2 + 4 = 7 です。65536 の基数 10 桁の合計は 6 + 5 + 5 + 3 + 6 = 25 です。

数字のルートは、数字が 1 つになるまで数字の合計を繰り返したときに得られるものです。65536 の数字の合計は 25 なので、数字の根は 2 + 5 = 7 です。

秘訣は次のとおりです。Z = X * Y の場合、DigitRoot(Z) = DigitRoot(DigitRoot(X) * DigitRoot(Y))。(読者への演習: 証明してください! ヒント: 加算のために同一の同一性を証明することから始めます。)

簡単に因数分解できる数があり、因数分解するのが最も簡単な数は 2 nである場合、桁根を再帰的に計算するのは簡単です: 2 16 = 2 8 * 2 8なので、 DigitRoot(2 16 ) = DigitRoot( DigitRoot(2 8 ) * DigitRoot(2 8 )) -- 問題を小さくしました。2 16を計算する必要はありません。2 8だけを計算すればよいのです。もちろん、このトリックは 2 30000で使用できます-- DigitRoot(DigitRoot(2 15000 * DigitRoot(2 15000 )) に分解します。2 15000の場合大きすぎる場合は、さらに分割します。解決できるほど小さな問題になるまで、分解を続けます。

わかる?

于 2013-04-27T14:47:19.270 に答える
1

http://blog.singhanuvrat.com/problems/sum-of-digits-in-abから:

public class Problem_16 {
    public long sumOfDigits(int base, int exp) {
        int numberOfDigits = (int) Math.ceil(exp * Math.log10(base));
        int[] digits = new int[numberOfDigits];
        digits[0] = base;
        int currentExp = 1;

        while (currentExp < exp) {
            currentExp++;
            int carry = 0;
            for (int i = 0; i < digits.length; i++) {
                int num = base * digits[i] + carry;
                digits[i] = num % 10;
                carry = num / 10;
            }
        }

        long sum = 0;
        for (int digit : digits)
            sum += digit;

        return sum;
    }

    public static void main(String[] args) {
        int base = 2;
        int exp = 3000;
        System.out.println(new Problem_16().sumOfDigits(base, exp));
    }
}

c#

public class Problem_16 {
    public long sumOfDigits(int base1, int exp) {
        int numberOfDigits = (int) Math.Ceiling(exp * Math.Log10(base1));
        int[] digits = new int[numberOfDigits];
        digits[0] = base1;
        int currentExp = 1;

        while (currentExp < exp) {
            currentExp++;
            int carry = 0;
            for (int i = 0; i < digits.Length; i++) {
                int num = base1 * digits[i] + carry;
                digits[i] = num % 10;
                carry = num / 10;
            }
        }

        long sum = 0;
        foreach (int digit in  digits)
            sum += digit;

        return sum;
    }
}


void Main()
{
     int base1 = 2;
        int exp = 3000000;
        Console.WriteLine (new Problem_16().sumOfDigits(base1, exp));

}
于 2013-05-07T04:21:20.500 に答える