2010年3月23日 星期二

國際資訊奧林匹亞獎牌計算

參加國際資訊奧林匹亞(IOI)競賽者大約有一半的選手可以獲得獎牌。In_d.txt即為被評為可以獲獎的名單(第1欄為國家代碼,第2欄為選手姓名,第3欄為其成績),在此名單中,金、銀、銅牌的分配約為1:2:3。試寫一程式依得分高任分配獎牌。輸出包括四部分:
由高至低排序,並將得獎類別寫在分數旁[G(金)、S(銀)、B(銅)]( 如輸出範例1)。
獎牌分配,即獲得金、銀、銅牌的個數 (如輸出範例2)。
得獎牌最多的國家,寫出國家代碼及獎牌 (不分類別) 數 (如輸出範例3)。
所有得獎者分數之平均數、最高分、最低分及全距 (即最高分與最低分的差距)(如輸出範例4)。

輸入範例(in_d.txt):
RSA Bruce Merry 333
HUN Balazs Racz 250
UKR Oleksandr lotko 230
ROM Bogdan Dumitru 360
VIE Nguyen N. Huy 430
SUI Peter Kaufmann 266
CRO Frane Saric 268
ROM Radu A. Stefan 150
BLR Ivan Miatselski 226
AUS Peter Hawkins 225
SVK Jan Senko 210
BUL Svetlin Nakov 208

輸出範例1
VIE Nguyen N. Huy 430 G
ROM Bogdan Dumitru 360 G
RSA Bruce Merr 333 S
CRO Frane Saric 268 S
SUI Peter Kaufmann 266 S
HUN Balazs Racz 250 S
UKR Oleksandr lotko 230 B
BLR Ivan Miatselski 226 B
AUS Peter Hawkins 225 B
SVK Jan Senko 210 B
BUL Svetlin Nakov 208 B
ROM Radu A. Stefan 150 B

輸出範例2
G 2
S 4
B 6

輸出範例3
ROM 2

輸出範例4
263.00 430.00 150.00 280.00

3 則留言:

  1. Private Sub Form_Load()
    Dim con(100) As String, grade(100) As Integer
    Dim all(100) As String, cong(100) As Integer

    Open App.Path & "/in.txt" For Input As #1

    i = 1
    Do Until EOF(1)
    Line Input #1, dat
    con(i) = Left(dat, 3)
    grade(i) = Right(dat, 3)
    all(i) = Mid(dat, Len(con(i)) + 1, Len(dat) - 6)
    i = i + 1
    Loop
    i = i - 1
    qw = i / 6
    p1 = 1 * qw: p2 = 2 * qw: p3 = 3 * qw
    Open App.Path & "/out1.txt" For Output As #2
    For q = 1 To i - 1
    For k = q + 1 To i
    If grade(q) < grade(k) Then
    Call change(grade(q), grade(k))
    Call change(con(q), con(k))
    Call change(all(q), all(k))
    End If
    Next k
    Select Case q
    Case Is <= p1
    Print #2, con(q); all(q); grade(q); " G"
    Case Is <= (p2 + p1)
    Print #2, con(q); all(q); grade(q); " S"
    Case Else
    Print #2, con(q); all(q); grade(q); " B"
    End Select
    Next q
    Close #2
    Close #1

    Open App.Path & "/out2.txt" For Output As #1
    Print #1, "G"; p1; vbCrLf; "S"; p2; vbCrLf; "B"; p3; vbCrLf
    Close #1
    Open App.Path & "/out4.txt" For Output As #1
    Max = 0: Min = 999
    For q = 1 To i
    Sum = Sum + grade(q)
    If grade(q) > Max Then Max = grade(q)
    If grade(q) < Min Then Min = grade(q)
    Next q
    Print #1, Format(Sum \ i, "##0.00"), Format(Max, "##0.00"), Format(Min, "##0.00"), Format(Max - Min, "##0.00")
    Close #1
    Open App.Path & "/out3.txt" For Output As #1
    Max = 1
    total = 1
    For q = 1 To i - 1
    For w = q + 1 To i
    If con(q) = con(w) Then
    r = q
    cong(q) = cong(q) + 1
    End If
    Next w
    If cong(q) >= Max Then
    Max = cong(q) + 1
    End If
    Next q
    Print #1, con(r), Max
    Close #1
    End Sub

    Public Sub change(z, b)
    c = z
    z = b
    b = c
    End Sub

    回覆刪除
  2. 阿揚好,
    1你在迴圈前,設定i=1;迴圈中,讓i=i+1;然後,在迴圈後,再去i=i-1。
    可以改成先設i=0,一進迴圈先i=i+1,這樣迴圈結束後,就不用再i=i-1了。
    少一個步驟。
    2你用了習慣的change,但是在這題中,一次要換三個東西,於是你call了三次。
    建議可以因題目不同而改變,這題每次要換三個東西,就直接去change中改變就好了。
    不過,要小心傳遞參數的方式,傳值,還是傳位址?
    3但是,你反而在排序中,偷吃步,想要一邊排序,一邊印出結果。於是,就出錯了。自己找一找,錯在那兒呢?
    4輸出3和輸出4對調了。可惜的小錯誤啊。
    5你的r=q放錯地方了。於是答案還是錯的。
    小錯誤太多,很危險。

    回覆刪除
  3. Dim player(100), con(100), sco(100) As Integer, conA(100) As Integer
    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    n = 1
    Do While Not EOF(1)
    Line Input #1, player(n)
    con(n) = Left(player(n), 3)
    sco(n) = Right(player(n), 4)
    n = n + 1
    Loop
    Close #1
    n = n - 1
    c1 = n / 6: c2 = n / 3
    For i = 1 To n
    For j = i To n
    If sco(i) < sco(j) Then
    change player(i), player(j)
    change con(i), con(j)
    change sco(i), sco(j)
    End If
    Next j
    Next i
    Max = 0: Min = 9999
    Open App.Path & "/out1.txt" For Output As #2
    For i = 1 To n
    If i <= c1 Then
    player(i) = player(i) & " G"
    ElseIf i > c1 And i <= c2 + c1 Then
    player(i) = player(i) & " S"
    Else
    player(i) = player(i) & " B"
    End If
    If sco(i) > Max Then Max = sco(i)
    If sco(i) < Min Then Min = sco(i)
    Sum = Sum + sco(i)
    Print #2, player(i)
    Next i
    Close #2
    Open App.Path & "/out2.txt" For Output As #3
    Print #3, "G " & c1
    Print #3, "S " & c2
    Print #3, "B " & n - c1 - c2
    Close #3
    Open App.Path & "/out3.txt" For Output As #4
    For i = 1 To n
    For j = 1 To n
    If con(i) = con(j) Then
    conA(i) = conA(i) + 1
    End If
    Next j
    Next i
    big = conA(1)
    k = 1
    For i = 2 To n
    If conA(i) > big Then
    big = conA(i)
    k = i
    End If
    Next i
    Print #4, con(k), conA(k)
    Close #4
    Open App.Path & "/out4.txt" For Output As #5
    Print #5, Format(Sum / n, "##0.00"), Format(Max, "##0.00"), Format(Min, "##0.00"), Format(Max - Min, "##0.00")
    Close #5
    End Sub

    Public Sub change(a, b)
    c = a
    a = b
    b = c
    End Sub

    回覆刪除