2011年8月5日 星期五

黑暗土地

內容 : 
黑 暗大陸的野人們突然四散開來,然後一瞬間大家都停了下來,靜止不動。部落首領走了出來,告訴努曼諾爾人這些野人們的座標位置,要求努曼諾爾人選出其中三 個,而選中的那三個野人所圍出來的土地就送給努曼諾爾人。現在,請從首領提供的座標資訊回答:最大的三角形土地面積可以是多少。若三個點的座標為 (a,b), (c,d), (e,f),則這三個點圍成的三角形面積為:
| 0.5*(ad+cf+be-bc-de-af) |
輸入說明 :
有多組測試資料,以EOF結尾。
輸入的第一行是一個正整數N (3<=N<=200),表示平面上有多少野人。接下來有N行,每行兩個整數,其中第k行代表第k個野人所在的座標 (Xk,Yk)
輸出說明 :
輸出可以取得的最大三角形土地面積,請四捨五入到小數點後兩位。
範例輸入 :
0 0 
0 1 
1 0 
1 1 
1 1 
5 3 
2 9
範例輸出 :
0.50 
15.00

10 則留言:

  1. Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Do While Not EOF(1)
    Input #1, N
    List1.Clear: List2.Clear: List3.Clear
    List1.AddItem " ": List2.AddItem " ": List3.AddItem 0

    For I = 1 To N
    Input #1, X, Y
    List1.AddItem X
    List2.AddItem Y
    Next I

    Call ABC(0, 1, 0, 0, 0)
    Print #2, Format(List3.List(0), "0.00")

    Loop
    Close #2
    Close #1
    End
    End Sub



    Sub ABC(ByVal A, ByVal S, ByVal B, ByVal C, ByVal D)
    If A = 3 Then
    X1 = Val(List1.List(B))
    Y1 = Val(List2.List(B))
    X2 = Val(List1.List(C))
    Y2 = Val(List2.List(C))
    X3 = Val(List1.List(D))
    Y3 = Val(List2.List(D))
    Call MAX(0.5 * (X1 * Y2 + X2 * Y3 + Y1 * X3 - Y1 * X2 - Y2 * X3 - X1 * Y3))
    Else
    For I = S To (List2.ListCount - 1)
    If A = 0 Then Call ABC(A + 1, (I + 1), I, C, D)
    If A = 1 Then Call ABC(A + 1, (I + 1), B, I, D)
    If A = 2 Then Call ABC(A + 1, (I + 1), B, C, I)
    Next I
    End If
    End Sub

    Sub MAX(A)
    If Val(A) > Val(List3.List(0)) Then
    List3.List(0) = A
    End If
    End Sub

    回覆刪除
  2. 佑好,
    程式應該正確,但是,
    你還是做太多浪費的東西了。
    從x個中,取3個的組合而已,不管這3個的順序為何,三角形面積相同。
    例如從4個中取3個,只有4種可能組合而已,你算太多個了。
    (那樣的話,如果有200個野人,你的程式大概跑不完的吧?)
    重新做,或者,另外出一題,「從x個中,取3個的組合」的題目試試。

    回覆刪除
  3. 佑好,
    可以在
    For I = S To (List2.ListCount - 1)
    If A = 0 Then Call ABC(A + 1, (I + 1), I, C, D)
    If A = 1 Then Call ABC(A + 1, (I + 1), B, I, D)
    If A = 2 Then Call ABC(A + 1, (I + 1), B, C, I)
    Next I
    這個迴圈中,加入判斷i不等於b,c,d中任一個,就可以省下很多次了。

    回覆刪除
  4. 熊掌好,

    首先先謝老師講解了,
    接著我將會將程式練的精細一點。
    很多題目沒講都沒有發現的方法,
    我會試著熟練如何看得更懂題目、
    和解題的技巧。

    所有能力都在使用中增加。

    回覆刪除
  5. 熊掌好,

    For I = S To (List2.ListCount - 1)
    If A = 0 Then Call ABC(A + 1, (I + 1), I, C, D)
    If A = 1 Then Call ABC(A + 1, (I + 1), B, I, D)
    If A = 2 Then Call ABC(A + 1, (I + 1), B, C, I)
    Next I

    如何加一個I判斷!!?

    回覆刪除
  6. 佑好,

    for i = s to list2.listcount-1
    if not(i=b or i=c or i=d) then
    If A = 0 Then Call ABC(A + 1, (I + 1), I, C, D)
    If A = 1 Then Call ABC(A + 1, (I + 1), B, I, D)
    If A = 2 Then Call ABC(A + 1, (I + 1), B, C, I)
    end if
    next i

    回覆刪除
  7. 熊掌好,

    如果不用not()

    if (i<>b or i<>c or i<>d) then
    嘛!!?

    回覆刪除
  8. 佑好,
    是。
    這就是大名頂頂的「迪摩根定律」。
    not(x or y) = (not x) and (not y)
    not(x and y) = (not x) or (not y)

    回覆刪除
  9. 熊掌好,

    剛剛去查了一下資料,

    還蠻特別的定律!!

    回覆刪除
  10. Dim x As String, n, s, u As Double
    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2

    Do While Not EOF(1)
    u = 0
    Input #1, n
    ReDim s(n)

    For i = 1 To n
    Input #1, x
    s(i) = x
    Next

    Call run(0, 0, "")
    Print #2, Format(u, "0.00")
    Loop

    '| 0.5*(ad+cf+be-bc-de-af) |

    Close
    Close
    End Sub

    Function run(m, p, k)

    If m = 3 Then
    pp = Split(p)
    a = pp(1): b = pp(2): c = pp(3): d = pp(4): e = pp(5): f = pp(6)
    ans = Abs(((a * d) + (c * f) + (b * e) - (b * c) - (d * e) - (a * f)) / 2)
    If ans > u Then u = ans
    Print u, a, b, c, d, e, f
    Else
    For i = 1 To n
    If InStr(k, i) = 0 Then Call run(m + 1, p & " " & s(i), k & " " & i)
    Next
    End If



    End Function

    回覆刪除