2011年5月24日 星期二

數學遊戲

在英國有一個數學遊戲,給參賽者一些正整數和一個目標數,參賽者必須在這些正整數間插入+、-、*或 / 的符號,使得最後計算的結果等於目標數。計算的方式是由左到右,而且不必管運算的優先順序(就是不管先乘除後加減那一套)。
在這個數學運算式中,有三個限制:
1. 正整數出現的次序不可改變,也就是說要與輸入的順序相同。
2. 因為目標數也是一個正整數,所以在運算的過程中,你只有在可以整除的情況下,才可以使用除法。 
3. 在運算的過程中,如果你用某一個運算符號,會導致產生的數超出-32000 ~ +32000的範圍,那麼你不可以採用此運算符號(也就是說,在運算的過程中都不允許有超出範圍的數出現)。
輸入規範
輸入檔案的第一列是1個整數n,代表接下來有多少組測試資料。
每組測試資料一列。每列的第一個整數 p(0 < p <100),代表要做運算的數有多少個。接下來有p個正整數,每列的最後一個數(即p+1個)為目標數。所有的數都小於32000,而每個數字間以一個空格分開(請參考輸入範例)。
輸出規範
每列測試資料輸出一列運算式,使得輸入的p個正整數運算的結果等於目標數。如果找不到這樣的運算式,請輸出"無解"。如果有多組運算式可以達成任務,請輸出任何一組均可。請參考輸出範例。


輸入範例
3
3 5 7 4 3
2 1 1 2000
5 12 2 5 1 2 4
輸出範例
5+7/4=3 
無解
12-2/5*1*2=4

3 則留言:

  1. Dim s, C, Anss As String

    Private Sub Form_Load()

    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    C = Split("+ - * /")

    Input #1, ins

    For i = 1 To ins
    Anss = ""
    Line Input #1, n
    s = Split(n)
    Call A1("")
    If Anss <> "" Then Print #2, Anss Else Print #2, "無解"
    Next


    Close
    Close

    End Sub


    Function A1(ans)

    If Len(ans) = (UBound(s) - 1) * 2 - 2 Then
    Call A2(ans)

    Else

    For i = 0 To UBound(C)
    Call A1(ans & " " & C(i))
    Next

    End If

    End Function


    Function A2(ans)
    Dim counts, sum As Integer
    If Left(ans, 1) = " " Then ans = Right(ans, Len(ans) - 1)

    counts = Split(ans)
    ans = ""
    sum = s(1)

    For i = 2 To UBound(s) - 1

    Select Case counts(i - 2)
    Case "+": sum = sum + s(i)
    Case "-": sum = sum - s(i)
    Case "*": sum = sum * s(i)
    Case "/": If sum Mod s(i) = 0 Then sum = sum / s(i) Else Exit For
    End Select

    Next



    If sum = s(UBound(s)) Then
    For i = 1 To UBound(s) - 1
    If i - 1 <= UBound(counts) Then ans = ans & s(i) & counts(i - 1) Else ans = ans & s(i)
    Next
    ans = ans & "=" & s(UBound(s))
    Anss = ans
    End If

    End Function

    回覆刪除
  2. Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\out.txt" For Output As #2
    Open App.Path & "\in.txt" For Input As #1

    Input #1, n
    For ii = 1 To n
    an = False
    Line Input #1, x
    a = Split(Right(x, Len(x) - 2))
    s = Split("+ - * /")
    y = UBound(a)
    Call c("", (y - 1) * 2, s)
    For i = 0 To List1.ListCount - 1
    m = Split(Right(List1.List(i), Len(List1.List(i)) - 1))
    For j = 0 To y - 2
    te = te & " " & a(j) & " " & m(j)
    Next
    List2.AddItem te & " " & a(y - 1)
    te = ""
    Next
    For i = 0 To List2.ListCount - 1
    k = Split(Right(List2.List(i), Len(List2.List(i)) - 1))
    For j = 1 To UBound(k) - 1 Step 2
    Select Case k(j)
    Case "+": k(j + 1) = Val(k(j - 1)) + Val(k(j + 1))
    Case "-": k(j + 1) = Val(k(j - 1)) - Val(k(j + 1))
    Case "*": k(j + 1) = Val(k(j - 1)) * Val(k(j + 1))
    Case "/": k(j + 1) = Val(k(j - 1)) / Val(k(j + 1))
    End Select
    Next
    If Val(a(y)) = Val(k(UBound(k))) Then
    Print #2, List2.List(i) & " = " & a(y)
    an = True: Exit For
    Else
    an = False
    End If
    Next
    If an = False Then Print #2, "無解"
    List1.Clear
    List2.Clear
    Next

    Close #1
    Close #2
    End
    End Sub
    Sub c(a1, b1, c1)
    If Len(a1) = b1 Then
    List1.AddItem a1
    Else
    For i = 0 To 3
    Call c(a1 & " " & c1(i), b1, c1)
    Next
    End If
    End Sub
    ----------------------
    in.txt
    5
    3 5 7 4 3
    2 1 1 2000
    5 12 2 5 1 2 4
    5 9 8 45 7 3 12
    3 48 57 2 18
    ---------------------
    out.txt
    5 + 7 / 4 = 3
    無解
    12 + 2 - 5 - 1 / 2 = 4
    無解
    無解

    回覆刪除
  3. arro,緣尉好,
    程式ok, 但是,在找範例輸入時,可以試著從已經的組合中,再去增加,例如
    5 + 7 / 4 = 3
    那麼加上個2,然後將解答改成6,是不是應該有解
    5 + 7 / 4 * 2 = 6
    讓自己的程式,試著做得出來。

    回覆刪除