2011年7月29日 星期五

排列組合的應用-2(99模擬)

子題2(11%):如果有一個客人來買這個菜攤的n 項商品,每類商品只能買1 項或不買,請
選手列出所有可能的購買組合。輸出之順序,應依照購買之總金額由高而低依序輸出。
輸入說明:
第1 行有1 個數字,代表n 的值。
第2 行有4 組數字,以逗號隔開,分別表示「肉」、「菜」、「蛋」、「果」每項商品的購買金額。
輸出說明:
每列輸出一組購買組合及其購買總金額,並至少以1 個空白隔開。其輸出方式為:每列均輸
出「肉菜蛋果」字串,但客人「購買」之商品名稱以「小括號」括起來。輸出之順序依購買
之總金額由高而低依序輸出,若有總金額相同者則不限順序。
輸入範例:【檔名:in-4-2.txt】
2
140, 64, 36, 84
輸出範例:【檔名:out-4-2.txt】
(肉)菜蛋(果) 224
(肉)(菜)蛋果 204
(肉)菜(蛋)果 176
肉(菜)蛋(果) 148
肉菜(蛋)(果) 120
肉(菜)(蛋)果 100

9 則留言:

  1. Dim N(4)
    Dim R() As String
    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Line Input #1, X
    Line Input #1, Y
    R = Split(Y, ",")
    N(0) = "肉": N(1) = "菜"
    N(2) = "蛋": N(3) = "果"

    Call AA("", -1)

    For i = 0 To (List1.ListCount - 1)
    Call BB(List1.List(i))
    Next i
    List1.Clear

    Do
    Max = Val(Mid(List2.List(0), 4))
    max2 = 0
    For i = 1 To (List2.ListCount - 1)
    If Max < Val(Mid(List2.List(i), 4)) Then
    max2 = i: Max = Val(Mid(List2.List(i), 4))
    End If
    Next i
    List3.AddItem List2.List(max2)
    List2.RemoveItem (max2)
    Loop Until List2.ListCount = 0

    For i = 0 To (List3.ListCount - 1)
    List1.AddItem CC(Left(List3.List(i), 2)) & Mid(List3.List(i), 3)
    Next i

    For i = 0 To (List1.ListCount - 1)
    Print #2, List1.List(i)
    Next i

    Close #2
    Close #1
    End
    End Sub

    Sub AA(ByVal A, ByVal B) '肉菜蛋果 做所有可能
    If Len(A) = 2 Then
    List1.AddItem A
    Else
    For i = 0 To 3
    If InStr(A, N(i)) = 0 And i > B Then Call AA(A & N(i), i)
    Next i
    End If
    End Sub

    Sub BB(A) '做計算
    total = 0
    For i = 0 To 1
    Select Case Mid(A, i + 1, 1)
    Case N(0): total = total + Val(R(0))
    Case N(1): total = total + Val(R(1))
    Case N(2): total = total + Val(R(2))
    Case N(3): total = total + Val(R(3))
    End Select
    Next i
    List2.AddItem A & " " & total
    End Sub

    Function CC(A) '取代
    ans = "肉菜蛋果"
    ans = Replace(ans, Mid(A, 1, 1), "(" & Mid(A, 1, 1) & ")")
    ans = Replace(ans, Mid(A, 2, 1), "(" & Mid(A, 2, 1) & ")")
    CC = ans
    End Function

    回覆刪除
  2. 佑好,
    花了大把時間,沒看清題義,還是沒用啊,可惜。
    「第1 行有1 個數字,代表n 的值」
    所以,程式錯誤。

    回覆刪除
  3. 佑好,
    另外一個改進點:
    For i = 0 To (List3.ListCount - 1)
    List1.AddItem CC(Left(List3.List(i), 2)) & Mid(List3.List(i), 3)
    Next i

    For i = 0 To (List1.ListCount - 1)
    Print #2, List1.List(i)
    Next i
    這兩個動作,不是只要作一次就好了嗎?

    回覆刪除
  4. 熊掌好,

    謝謝老師,
    我只有做2種的情況,
    我反而發現一些不用做的。
    EX:
    ans = Replace(ans, Mid(A, 1, 1), "(" & Mid(A, 1, 1) & ")")
    ans = Replace(ans, Mid(A, 2, 1), "(" & Mid(A, 2, 1) & ")")
    可以改成
    For i = 1 To X
    ans = Replace(ans, Mid(A, i, 1), "(" & Mid(A, i, 1) & ")")
    Next i

    Dim N(4)
    Dim X
    Dim R() As String
    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, X
    Line Input #1, Y
    R = Split(Y, ",")
    N(0) = "肉": N(1) = "菜"
    N(2) = "蛋": N(3) = "果"

    Call AA("", -1)

    For i = 0 To (List1.ListCount - 1)
    Call BB(List1.List(i))
    Next i
    List1.Clear

    Do
    Max = Val(Mid(List2.List(0), 4))
    max2 = 0
    For i = 1 To (List2.ListCount - 1)
    If Max < Val(Mid(List2.List(i), 4)) Then
    max2 = i: Max = Val(Mid(List2.List(i), 4))
    End If
    Next i
    List3.AddItem List2.List(max2)
    List2.RemoveItem (max2)
    Loop Until List2.ListCount = 0

    For i = 0 To (List3.ListCount - 1)
    List1.AddItem CC(Left(List3.List(i), X)) & Mid(List3.List(i), X + 1)
    Print #2, List1.List(i)
    Next i

    Close #2
    Close #1
    End
    End Sub

    Sub AA(ByVal A, ByVal B) '肉菜蛋果 做所有可能
    If Len(A) = X Then
    List1.AddItem A
    Else
    For i = 0 To 3
    If InStr(A, N(i)) = 0 And i > B Then Call AA(A & N(i), i)
    Next i
    End If
    End Sub

    Sub BB(A) '做計算
    total = 0
    For i = 0 To 2
    Select Case Mid(A, i + 1, 1)
    Case N(0): total = total + Val(R(0))
    Case N(1): total = total + Val(R(1))
    Case N(2): total = total + Val(R(2))
    Case N(3): total = total + Val(R(3))
    End Select
    Next i
    List2.AddItem A & " " & total
    End Sub

    Function CC(A) '取代
    ans = "肉菜蛋果"
    For i = 1 To X
    ans = Replace(ans, Mid(A, i, 1), "(" & Mid(A, i, 1) & ")")
    Next i
    CC = ans
    End Function

    回覆刪除
  5. 佑好,
    還是錯小地方,
    For i = 0 To 2
    Select Case Mid(A, i + 1, 1)
    Case N(0): total = total + Val(R(0))
    Case N(1): total = total + Val(R(1))
    Case N(2): total = total + Val(R(2))
    Case N(3): total = total + Val(R(3))
    End Select
    Next i
    這裡的i, 應該到3吧。

    回覆刪除
  6. Dim NeeD, P(4), N

    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2


    N = Split("空 肉 菜 蛋 果")

    Input #1, NeeD
    Input #1, P(1), P(2), P(3), P(4)

    Call cot("")
    Call cot3
    Close
    Close
    End Sub


    Sub cot(a)

    If Len(a) = NeeD Then
    Call cot2(a)

    Else
    For i = 1 To 4
    If InStr(a, N(i)) = 0 Then Call cot(a & N(i))
    Next
    End If

    End Sub



    Sub cot2(a)
    mm = "肉菜蛋果"
    For i = 1 To NeeD
    m = Mid(a, i, 1)

    Select Case m
    Case "肉": ans = ans + P(1)
    Case "菜": ans = ans + P(2)
    Case "蛋": ans = ans + P(3)
    Case "果": ans = ans + P(4)
    End Select



    mm = Replace(mm, m, "(" & m & ")")
    Next
    ans2 = ans & " " & mm & " " & ans


    Dim ch As Boolean
    For i = List1.ListCount - 1 To 0 Step -1
    If ans2 = List1.List(i) Then ch = True
    Next

    If ch = False Then List1.AddItem ans2

    End Sub


    Sub cot3()
    For i = List1.ListCount - 1 To 0 Step -1
    k = Right(List1.List(i), Len(List1.List(i)) - 5)
    Do While Left(k, 1) = " "
    k = Right(k, Len(k) - 1)
    Loop
    Print #2, k
    Next
    End Sub

    回覆刪除
  7. arro好,
    雖然大部分正確,但是,
    你為了用 listbox的排序,在前頭放了個價錢的數字,這裡有兩個問題,
    1是放在那兒還是文字,排序上有可能錯。
    2是k = Right(List1.List(i), Len(List1.List(i)) - 5)
    你還是假設那個價錢最多就是5位數,如果超過呢?
    (解決方法是加長到數字的最長,或是,放棄listbox的排序,而是用雙陣列的排序法,以其中一個陣列的值來排序,但是在互換時,記得另一個陣列也要跟著一起互換)

    另外,你在

    For i = List1.ListCount - 1 To 0 Step -1
    If ans2 = List1.List(i) Then ch = True
    Next

    If ch = False Then List1.AddItem ans2
    這兒為了怕重複而去檢查了一次,這兒程式並沒有出錯。
    但是,會有重複的嗎? 你寫的排列組合,應該沒有重複的吧?

    回覆刪除
  8. 熊掌好,

    開程式來看,
    已經修改好了:P。
    昨天沒網路可以用@"@~

    Dim R() As String
    Dim N(4)
    Dim KG() As String
    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Line Input #1, X
    R = Split(X, ",")
    Line Input #1, Y
    KG = Split(Y, ",")
    N(0) = "肉": N(1) = "菜"
    N(2) = "蛋": N(3) = "果"

    Call AA("")

    For i = 0 To (List1.ListCount - 1)
    Call BB(List1.List(i))
    Next i

    List1.Clear

    Do
    Max = Val(Mid(List2.List(0), 6))
    max2 = 0
    For i = 1 To (List2.ListCount - 1)
    If Max < Val(Mid(List2.List(i), 6)) Then
    max2 = i: Max = Val(Mid(List2.List(i), 6))
    End If
    Next i
    List1.AddItem List2.List(max2)
    List2.RemoveItem (max2)
    Loop Until List2.ListCount = 0

    For i = 0 To (List1.ListCount - 1)
    Print #2, List1.List(i)
    Next i

    Close #2
    Close #1
    End
    End Sub

    Sub AA(ByVal A) '肉菜蛋果 做所有可能
    If Len(A) = 4 Then
    List1.AddItem A
    Else
    For i = 0 To 3
    If InStr(A, N(i)) = 0 Then Call AA(A & N(i))
    Next i
    End If
    End Sub

    Sub BB(A) '做計算
    total = 0
    For i = 0 To 3
    Select Case Mid(A, i + 1, 1)
    Case N(0): total = total + Val(R(0)) * Val(KG(i))
    Case N(1): total = total + Val(R(1)) * Val(KG(i))
    Case N(2): total = total + Val(R(2)) * Val(KG(i))
    Case N(3): total = total + Val(R(3)) * Val(KG(i))
    End Select
    Next i
    List2.AddItem A & " " & total
    End Sub

    回覆刪除
  9. 佑好,
    但是你還是沒有解決,那數字如果大於6位數呢?
    數字的那部分,請另外放在一個listbox或是陣列中,
    那麼就沒有幾位數的問題了。

    回覆刪除