数学に関する問題です。

すべての自然数を、順番につなげて書いたとします。
123456789101112131415161718192021222324252627282930…
100万個目の数字は何でしょう?
1番早く正答を送ってきた人、ベストアンサーです。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2012/03/11 10:31:48
  • 終了:2012/03/11 12:54:24

ベストアンサー

id:yarukimedesu No.1

yarukimedesu回答回数283ベストアンサー獲得回数482012/03/11 11:19:13

 100万個目の数字は1となると思います。

 計算というには、地道なことをしましたが…。

 1~9は1文字ずつ追加。9文字追加。
 10~99は2文字ずつ追加。つまり2×(99-9)=180文字追加。
 100~999は3文字ずつ追加。つまり3×(999-99)=2700文字追加。
 1000~9999は4文字ずつ追加。つまり4×(9999-999)=36000文字追加。
 10000~99999は5文字ずつ追加。つまり5×(99999-9999)=450000文字追加。

 これまで、追加さらた文字を合計すると。48万8889文字となります。100万文字目まで、後、51万1111文字。これを6で割ってみると、8万5185.1666…となります。

 余りを省いて、8万5185×6が51万1110文字。それに48万8889文字を足して、99万9999文字。

 99万9999文字目は、6桁の数字の1の桁になっているので、100万文字目は、「18万ほにゃらら」の「1」じゃあないかと。

他5件のコメントを見る
id:nyobunaga618

素晴らしい!!!!!
18万ほにゃららは、185185ですね。

2012/03/11 12:56:06
id:nyobunaga618

プログラムもいらないしいい解だと思います。

2012/03/15 18:34:31
  • id:nyobunaga618
    計算式込みでお願いします
  • id:kokorohamoe
    #include "stdafx.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>

    int count(int n){
    if(n<10){
    return 1;
    }
    if(n<100){
    return 2;
    }
    if(n<1000){
    return 3;
    }
    if(n<10000){
    return 4;
    }
    if(n<100000){
    return 5;
    }
    if(n<1000000){
    return 6;
    }
    exit(1);
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    int cnt = 0;
    int start = 0;

    while(true){
    cnt += count(start);
    if(cnt >= 1000000){
    std::cout << "cnt = " << cnt ;
    std::cout << "num = " << start ;
    std::cout <<std::endl;
    exit(1);
    }
    start++;
    }



    return 0;
    }

    答え
    cnt = 1000000num = 185184

    いちおう もう1つの答えを
    プログラムで総当りした所
    0を自然数に含めた場合
    4です(w)
  • id:kokorohamoe
    log取れというコメントが個人的にあったので
    問題より 6桁の整数の桁数の和はおよそ600万桁になるので、解がこの範囲にあることは自明。
    logを使った場合、それの基数が10であることを別途デバッグする必要性があるので ifで代理。

    より簡単なロジックで同じ回答がでるのであれば、より簡単なロジックを使う派閥です。
  • id:tdoi
    より簡単ならロジックで済むなら、簡単なロジックを使うことは正しいとは思いますが、ロジックがシンプルなのと、ダラダラ書くのとは違うかなと。例えば、こんな書き方だってできる訳で。

    int count1(int number)
    {
    std::stringstream stream;
    stream << number;
    return stream.str().size();
    }

    int count2(int number, int total = 0)
    {
    if (number < 10) {
    return total + 1;
    }
    return count2(number / 10, total + 1);
    }

    int count3(int number)
    {
    return (number == 0) ? 1 : static_cast<int>(log10(number) + 1);
    }

    int main(int argc, char** argv)
    {
    int total = 0;
    int number = 1;

    while (total < 1000000) {
    total += count3(number);
    ++number;
    }
    --number;
    std::cout << "total = " << total << ", num = " << number << std::endl;
    }

    logに関しては、「それの基数が10であることを別途デバッグする」の意味が分かりませんでしたが、確かに0の場合分けは厳密には必要ですよね。後は、誤差もちょっと気になったりはします。0に関してはlog10の引数には自然数しか渡さないという前提知識で無視するって手もあるかもですね。
    ちなみにcount1は遅いです。
  • id:rsc96074
     これ簡単かも。
    >|javascript|
    <script>
    sum=0;
    bk=sum; // 1つ前の足される数までの個数の合計
    num=1; // 足される数
    for(;;){
    sum+=num.toString().length;
    if(sum>=1000000) break;
    bk=sum;
    num++;
    }
    document.write(bk,"|",num,"<br>");
    document.write("∴",num.toString().charAt(1000000-bk-1));
    </script>
    ||<
  • id:garyo
    思いっきりべたに計算してみた。

    s=""
    i=0
    while s.size < 1000000
    i=i+1
    s=s+i.to_s
    end
    puts s[1000000-1]
    puts i

    実行結果
    1
    185185
  • id:garyo
    早くしてみた
    size=0
    i=0
    while size < 1000000
    i = i + 1
    size = size + i.to_s.size
    end
    puts i.to_s[1000000 - 1 - size]
    puts i
  • id:nyobunaga618
    うわっはあ……。
    皆さんありがとうございます

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません