2010年1月14日 星期四

第一次儲備選手選拔試卷第六題

從指定目錄"in.txt"讀取一數字N,求N!的結果數值中,從右邊算來第一個不是0的數字,輸出至指定目錄"out.txt"。
( 0 < N < 10000 )

輸入範例:10

輸出範例:8

9 則留言:

  1. 小提示:
    這題中的N,要求可以算到很大,所以不能直接求N階乘,會容易溢位的。
    而是直接找到每次乘積的最右邊非0的數,去乘下一個數。
    熊掌

    回覆刪除
  2. Private Sub Form_Activate()
    Open App.Path & "\in.txt" For Input As #1
    Input #1, x
    Sum = 1
    For i = 2 To x
    Sum = Sum * i
    Next i
    For i = 0 To Len(Sum) - 1
    If Mid(Sum, Len(Sum) - i, 1) <> "0" Then
    ans = Mid(Sum, Len(Sum) - i, 1)
    Open App.Path & "\out.txt" For Output As #2
    Print #2, ans
    Close #2
    Exit For
    End If
    Next i
    Close #1
    End Sub

    回覆刪除
  3. for i = 2 to x
    sum = sum * i
    next i
    這三行的sum一下子就溢位了。
    請重新思考。
    熊掌

    回覆刪除
  4. Private Sub Form_Load()

    Open App.Path & "\in.txt" For Input As #1
    Input #1, x
    Close #1

    Open App.Path & "\out.txt" For Output As #2

    For i = 1 To x - 1
    x = x * i
    Next i

    Do
    y = Val(x Mod 10)
    If y <> 0 Then
    Print #2, y
    Exit Do
    End If
    x = x \ 10
    Loop

    Close #2

    End Sub

    回覆刪除
  5. 阿瑋好,
    你的情形和高仔的狀況一樣,會溢位的。這一題題目的要求是要可以算到 N是10000的情形呢。
    有些時候在找出如何解題時,可以先試著寫寫幾個例子,看看會不會有什麼規則出現,利用這些規則來寫程式。
    這題並不是要做「大數」相乘的問題,不需要用字串或字串陣列來表示數字的。

    回覆刪除
  6. Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Input #1, x
    Close #1

    Open App.Path & "\out.txt" For Output As #2
    If x = 0 Then
    y = 0
    Else
    y = 1
    For i = 1 To x - 1
    ans = y * (i + 1)

    For j = 1 To Len(ans)
    y = Mid(ans, j, 1)

    k = 1
    While y = 0
    y = Mid(ans, k, 1)
    k = k + 1
    Wend
    Next j
    Next i
    End If

    Print #2, y
    Close #2
    End Sub

    謝謝老師的講解!!
    哈哈。Apple的保護膜好漂亮>

    回覆刪除
  7. 皓好,
    似乎你的程式會對,只是,似乎是怪怪地找到答案的。
    首先
    for i = 1 to x-1
    ans=y*(i+1)
    ->
    這為什麼不改成
    for i = 2 to x
    ans = y*i
    再來,想找到最後那個非0的數,你用了奇怪的迴圈,(而且又是用數字的長度,怪怪的,下次我再去找找len這個函數對於參數的設定,而且,小心,用這類的函數有時候是不被允許的。)是從數字的左邊取過來的,應該是從右邊取吧?
    用你的寫法可以改成:
    for j = len(ans) to 1 step -1
    y = mid(ans,j,1)
    if y <> 0 then exit for
    next j
    這樣就可以找到第一個非0的數了。
    只是,這樣還不滿意,請再想想用除以10取餘數的方式,配合整除10去掉尾巴的0的這兩個計算,得到右邊數來第1個非0的數字。
    再加油。
    熊掌 在北海道滑完雪,吃過烤肉的夜間發呆時間。(真好)

    回覆刪除
  8. 恩好>

    我去試一下看看
    謝謝建議

    回覆刪除
  9. Public Sub Form_Load()
    Dim ans As Long
    Dim an As String
    Me.Hide
    Open App.Path & "/in.txt" For Input As #1
    Open App.Path & "/out.txt" For Output As #2
    Input #1, x
    ans = 1
    For i = 1 To x
    ans = ans * i
    an = Trim(Str(ans))
    For j = Len(an) To 1 Step -1
    k = Mid(an, j, 1)
    If Val(k) <> 0 Then
    an = Right(an, Len(an) - j + 1)
    ans = Val(an)
    m = k
    Exit For
    End If
    Next j
    Next i
    Print #2, m
    Close #2
    Close #1
    End
    End Sub

    15分49秒

    回覆刪除