2011年8月6日 星期六

棒球九宮格

內容 : 
小明很喜歡棒球。某天晚上跟媽媽到家裡附近逛夜市,突然發現多了一個棒球九宮格的遊戲攤位(如圖一)。遊戲規則如下:一開始九宮格內會分別擺上一個木板,玩家站在距離九宮格板數公尺外,總共可以丟出九顆球。被命中的格子裡的木板會倒下;若球丟出範圍外,或是剛好丟在九宮格的框架上,則所有格子都會維持原樣。一旦將球丟出去,可用的球數就減少一,直到將九顆球丟完為止。

九顆球都丟完之後,夜市的老闆會根據倒下的格子來檢查連成幾條線,以決定獎品的好壞。依照老闆的規定,只要以下其中一組格子裡的木板同時倒下,則算連成一線:{1,2,3}、{4,5,6}、{7,8,9}、{1,4,7}、{2,5,8}、{3,6,9}。舉例來說,若2、3、5、7、8、9這六個格子中的木板都倒下,則2、5、8連成一線,且7、8、9也連成一線,總共連成兩條線。(請注意,依規則3、5、7不算連成一線。)此外,老闆也會根據丟到的格子號碼,計算"加碼積分",提供額外的獎賞,詳細規則如下:丟到5號得2分,丟到{2、4、6、8}中的任一號碼得5分,丟到{1、3、7、9}中的任一號碼得8分。例如若2、5、8、9這四格被丟中,則加碼積分為20分。請注意,重複丟到的號碼只算一次分數。
請寫一個程式來模擬玩棒球九宮格的遊戲。為了方便貣見,我們將用二維座標來定義九宮格的位置,如圖二所示。每一格都是相同大小的正方形,7號格左下角的座標為(0,0),3號格右上角座標為(30,30)。在模擬的過程中,會提供每一顆球丟在九宮格上的座標位置。為了簡化問題,若某顆球丟在九宮格上的座標位於某一格內,則判斷打到該格;如果座標位於某一格的邊上,則判斷為打到框架,沒有任何格子被打到。舉例來說,假設一顆球丟到座標位置為(7,13)的地方,由於落在4號格之內,判定打到4號格;假設有另一顆球打在(10,2)(或(10,20))的座標位置,則因為落在框架上,沒有任何格子被打到。當然如果座標落在九宮格外的區域,也沒有任何格子被丟中。
輸入說明 :
輸入總共有9行。每一行有兩個整數x和y (-20 <= x,y <= 50,x與y由一個空白隔開),代表球的座標。
輸出說明 :
請輸出丟出9顆球之後,根據夜市老闆的規則總共連成幾條線;另外請根據丟到的格子號碼,算出加碼積分。
範例輸入 :
輸入範例1: 
7 13 
10 2 
5 8 
-9 19 
11 35 
3 23 
18 0 
0 18 
40 22 
輸入範例2: 
12 22 
15 11 
3 20 
3 22 
33 27 
28 28 
16 5 
22 -5 
35 35 
範例輸出 :

輸出範例1: 
1 21 
輸出範例2: 
2 28

3 則留言:

  1. 題目非常的冗長=口=


    Dim A(3, 3) As Boolean
    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2

    Dim N(3, 3) As Integer
    N(2, 2) = 2
    N(2, 3) = 5: N(1, 2) = 5: N(3, 2) = 5: N(2, 1) = 5
    N(1, 3) = 8: N(3, 3) = 8: N(1, 1) = 8: N(3, 1) = 8

    For i = 1 To 9
    Input #1, X, Y
    If X Mod 10 <> 0 And Y Mod 10 <> 0 And X > 0 And Y > 0 And X < 30 And Y < 30 Then
    X = X \ 10
    Y = Y \ 10
    A(X + 1, Y + 1) = True
    End If
    Next i

    total = 0
    For i = 1 To 3
    For j = 1 To 3
    If A(i, j) = True Then total = total + N(i, j)
    Next j, i


    Print #2, L() & " " & total

    Close #2
    Close #1
    End
    End Sub

    Function L()
    ans = 0
    If Three_equal(A(1, 1), A(1, 2), A(1, 3)) = True Then ans = ans + 1
    If Three_equal(A(2, 1), A(2, 2), A(2, 3)) = True Then ans = ans + 1
    If Three_equal(A(3, 1), A(3, 2), A(3, 3)) = True Then ans = ans + 1
    If Three_equal(A(1, 1), A(2, 1), A(3, 1)) = True Then ans = ans + 1
    If Three_equal(A(1, 2), A(2, 2), A(3, 2)) = True Then ans = ans + 1
    If Three_equal(A(1, 3), A(2, 3), A(3, 3)) = True Then ans = ans + 1
    L = ans
    End Function

    Function Three_equal(AA, BB, CC) As Boolean
    If AA = BB And BB = CC And CC = True Then Three_equal = True
    End Function

    回覆刪除
  2. 佑好,
    程式正確。
    改進點1:
    Function Three_equal(AA, BB, CC) As Boolean
    If AA = BB And BB = CC And CC = True Then Three_equal = True
    End Function
    這個函數的傳回值,不要用true / false(哦,你程式中並沒有處理false,不小心會出問題的)
    而是讓函數傳回1或0,然後上一層的函數就直接去將值給加起來,不用再一次的判斷。
    改進點2:
    陣列A(X + 1, Y + 1) = True 的值,也改成1或0,那麼
    If A(i, j) = True Then total = total + N(i, j)
    也可以改成不用if了,直接
    total = total + n(i,j)*a(i,j)

    回覆刪除
  3. Dim hit As String, a As Integer, b As Integer, L As Integer, P As Integer, lines
    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    hit = 0

    Do While Not EOF(1)
    Input #1, a, b
    Call checkhit(a, b)
    Loop

    Call checkline
    Print #2, lines & " " & P
    Close
    Close
    End
    End Sub


    Sub checkhit(x, y)

    'out-check
    If x > 30 Or x < 0 Or y > 30 Or y < 0 Then Exit Sub
    'nothit-check
    If x Mod 10 = 0 Or y Mod 10 = 0 Then Exit Sub
    'in
    If x < 10 And y > 20 Then Call Addhit(1)
    If x < 20 And x > 10 And y > 20 Then Call Addhit(2)
    If x > 20 And y > 20 Then Call Addhit(3)

    If x < 10 And y > 10 And y < 20 Then Call Addhit(4)
    If x < 20 And x > 10 And y > 10 And y < 20 Then Call Addhit(5)
    If x > 20 And y > 10 And y < 20 Then Call Addhit(6)

    If x < 10 And y < 10 Then Call Addhit(7)
    If x < 20 And x > 10 And y < 10 Then Call Addhit(8)
    If x > 20 And y < 10 Then Call Addhit(9)

    End Sub

    Sub Addhit(m)
    If InStr(hit, m) = 0 Then hit = hit & " " & m
    End Sub

    Sub checkline()
    Dim hited(9), k
    k = Split(hit)
    Print hit
    For i = 1 To UBound(k)
    hited(k(i)) = k(i)
    Next

    If hited(1) <> 0 And hited(2) <> 0 And hited(3) <> 0 Then lines = lines + 1
    If hited(4) <> 0 And hited(5) <> 0 And hited(6) <> 0 Then lines = lines + 1
    If hited(7) <> 0 And hited(8) <> 0 And hited(9) <> 0 Then lines = lines + 1
    If hited(1) <> 0 And hited(4) <> 0 And hited(7) <> 0 Then lines = lines + 1
    If hited(2) <> 0 And hited(5) <> 0 And hited(8) <> 0 Then lines = lines + 1
    If hited(3) <> 0 And hited(6) <> 0 And hited(9) <> 0 Then lines = lines + 1

    If hited(5) <> 0 Then P = P + 2
    For i = 1 To 9
    If hited(i) <> 0 And i Mod 2 = 1 And i <> 5 Then P = P + 8
    If hited(i) <> 0 And i Mod 2 = 0 Then P = P + 5
    Next

    End Sub

    回覆刪除