顯示具有 程式選訓 標籤的文章。 顯示所有文章
顯示具有 程式選訓 標籤的文章。 顯示所有文章

2018年8月6日 星期一

商競程式103模_解題記錄

試題連結 (商業類技藝技賽_103年_程式設計_模擬題)

用VB10寫在Form_Load,讀檔統一如下,然後呼叫fxx,每題讀檔就不重複


讀檔寫檔

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Hide()
        FileOpen(1, "in1.txt", 1)
        FileOpen(2, "in2.txt", 1)
        FileOpen(3, "out.txt", 2)
        For fn = 1 To 2
            If fn = 2 Then PrintLine(3)
            Dim n As Short = LineInput(fn)
            For k = 1 To n
                Dim s As String = LineInput(fn)
                PrintLine(3, fxx(s))
            Next
        Next
        End
    End Sub
   ...
   每一題 解題部份
   ...
End Class

P11 判斷是否為質數

   Function fxx(ByVal x As Integer) As String
        If x < 2 Then Return "N"
        For i = 2 To Math.Sqrt(x)
            If x Mod i = 0 Then Return "N"
        Next
        Return "Y"

    End Function

P12 解二元一次聯立方程式之根

     Function fxx(ByVal s As String) As String
        Dim dat() = s.Split(",")
        Dim a As Integer = dat(0), b As Integer = dat(1)
        Dim c As Integer = dat(2), d As Integer = dat(3)
        Dim ee As Integer = dat(4), f As Integer = dat(5)
        Dim x As Integer = (c * ee - b * f) / (a * ee - b * d)
        Dim y As Integer = (c * d - a * f) / (b * d - a * ee)
        Return x & "," & y
    End Function

P21 摩斯電碼
    ' tbl 字串陣列宣告為同一列,因版面分為多列顯示     Dim tbl() As String = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."}
    Function fxx(ByVal s As String) As String
        Dim dat() = s.Split(" ")
        fxx = ""
        For i = 0 To UBound(dat)
            fxx &= Chr(Array.IndexOf(tbl, dat(i)) + 65)
        Next
    End Function

P22 凱撒密碼

   Function fxx(ByVal s As String) As String
        fxx = ""
        For i = 1 To s.Length
            Dim c As Char = Mid(s, i, 1)
            If c < "A" Or c > "Z" Then Continue For
            Dim k As Integer = Asc(c) - 65
            k = (k + 3) Mod 26
            fxx &= Chr(65 + k)
        Next
   End Function


P31 是否為樹

    Const MaxN As Integer = 20 '編號 0~20
    Dim adj(MaxN, MaxN) As Boolean '相鄰矩陣
    Dim nds(MaxN) As Boolean '是否為節點
    Dim vst(MaxN) As Boolean '是否訪過
    Sub dfs(ByVal u As Integer) '由 u深訪
        vst(u) = True
        For v = 0 To MaxN
            If adj(u, v) And Not vst(v) Then dfs(v) '相鄰且 v 未訪過
        Next
    End Sub
    Function fxx(ByVal s As String) As String
        s = Trim(s) : ttrim(s, "  ", " ") : ttrim(s, ", ", ",") : ttrim(s, " ,", ",")
        Dim st As Integer ' 起點
        Dim egs() = s.Split(" ")  '邊
        Dim egcnt As Integer = egs.Length  '邊數
        Array.Clear(adj, 0, (MaxN + 1) * (MaxN + 1))
        Array.Clear(nds, 0, MaxN + 1)
         For i = 0 To UBound(egs)
            Dim xy() = egs(i).Split(",") '分成 x,y
            Dim x As Integer = xy(0), y As Integer = xy(1)
            adj(x, y) = True : adj(y, x) = True
            nds(x) = True : nds(y) = True
            st = x
        Next
        Dim ndcnt As Integer = 0  '節點數
        For i = 0 To MaxN
            If nds(i) Then ndcnt += 1
        Next
         If ndcnt <> egcnt + 1 Then Return "F" '點、邊的數不符 樹的規定
        Array.Clear(vst, 0, MaxN + 1)
        dfs(st)
        For i = 0 To MaxN  '是節點,但未訪過,不連通就不是樹
            If nds(i) And Not vst(i) Then Return "F"
        Next
        Return "T"
    End Function
    Sub ttrim(ByRef s As String, ByVal a As String, ByVal b As String)
        Do While (InStr(s, a) > 0)
            s = s.Replace(a, b)
        Loop

    End Sub


P32 樹葉至根的路徑
因每筆測資多行,將 fn 也傳入 fxx , for k=1 to n 內修改

           For k = 1 To n
                If k > 1 Then LineInput(fn) '兩組間有空白列
                Dim m As Integer = LineInput(fn) 'm個邊,需再讀入
                PrintLine(3, fxx(fn, m))
            Next

    Const MaxN As Integer = 99 '根父 99
    Function fxx(ByVal fn As Integer, ByVal m As Integer) As String '有 m個節點及父,需讀入
        Dim fa(MaxN) As Integer '父編號
        Dim ch(MaxN) As Boolean '有子?
        For i = 1 To m
            Dim s1 As String = LineInput(fn)
            '    MsgBox(s1)
            Dim dat() = s1.Split(",")
            Dim x As Integer = dat(0), y As Integer = dat(1)
            fa(x) = y
            ch(y) = True
        Next
        '因題目規定節點編號 0~m-1,不會有空號
        fxx = ""
        For j = 0 To m - 1
            If Not ch(j) Then   ' 沒有兒子的就是葉子
                Dim cnt = 0    '往上走至根之間的節點數
                Dim s = ""     ' 每葉輸出一列
                Dim p = fa(j)
                Do Until fa(p) = 99
                    If cnt > 0 Then s &= ("," & p) Else s &= p
                    cnt += 1
                    p = fa(p)
                Loop
                If cnt > 0 Then s = "{" & s & "}" Else s = "N"
                fxx &= j & ":" & s & vbNewLine
            End If
        Next

    End Function


P41 撲克牌

Dim fs(5) As Integer  '0,1,2,3
Dim pt(5) As Integer ' 0,1,....12

Function stra() As Boolean  ' 是否為順子
    For i = 1 To 4
        If pt(i) - 1 <> pt(i - 1) Then Return False
    Next
    Return True
End Function

Function flush() As Boolean  ' 是否為同花
    For i = 1 To 4
        If fs(i) <> fs(i - 1) Then Return False
    Next
    Return True
End Function

Function fxx(ByVal s As String) As String
    Dim dat() = s.Split(" ")
    For i = 0 To 4
        Dim j = dat(i) - 1  '減1
        fs(i) = j \ 13
        pt(i) = j Mod 13
    Next
    Array.Sort(pt, 0, 5)
    Dim st As Boolean = stra()
    Dim fl As Boolean = flush()
    Dim pair(4) As Integer 'pair(2)對子數、 pair(3)三條數、 pair(4)四條數
    Dim cnt As Integer = 1
    For i = 1 To 4
        If pt(i) = pt(i - 1) Then
            cnt += 1
        Else
            pair(cnt) += 1
            cnt = 1
        End If
    Next
    pair(cnt) += 1
    If (Not st And pt(0) = 0 And pt(4) = 12) Then '有可能 A 10 J Q K
        pt(0) = 13
        Array.Sort(pt, 0, 5)
        st = stra()
    End If

    If fl And st Then

        Return 7
    ElseIf pair(4) = 1 Then
        Return 6
    ElseIf pair(3) = 1 And pair(2) = 1 Then
        Return 5
    ElseIf st Then
        Return 4
    ElseIf pair(3) = 1 Then
        Return 3
    ElseIf pair(2) = 2 Then
        Return 2
    ElseIf pair(2) = 1 Then
        Return 1
    Else
        Return 0
    End If

End Function

P42 樂透
因每筆測資2行,一次讀兩列傳給  fxx , for k=1 to n 內修改

            For k = 1 To n

                Dim s1 As String = LineInput(fn)
                Dim s2 As String = LineInput(fn)
                PrintLine(3, fxx(s1, s2))
            Next
   Function fxx(ByVal s1 As String, ByVal s2 As String) As String
        Dim dat1() = s1.Split(",")
        Dim dat2() = s2.Split(",")
        Dim a(5), b(5) As Integer
        For i = 0 To 4
            a(i) = dat1(i)
            b(i) = dat2(i)
        Next
        Array.Sort(a, 0, 5) '可能未排序
        Array.Sort(b, 0, 5) '可能未排序
        Dim ai As Integer = 0, bi As Integer = 0
        Dim cnt = 0
        Do While ai < 5 And bi < 5
            If a(ai) = b(bi) Then
                cnt += 1
                ai += 1 : bi += 1
            ElseIf a(ai) > b(bi) Then
                bi += 1
            Else
                ai += 1
            End If
        Loop
        Return cnt
    End Function

2018年1月23日 星期二

To Z2A 程式選訓(2018-124)

資2忠程式選訓   寒輔進度

 去年的練習題(各年較簡單題型)




 12/20,12/27 的五題練習參考解(1)~(3)

      12/27 五題參考解 - (4) (5)

  1/3 的二題練習題目


以上的題目壓縮如下

To Z2A 程式選訓(2018-103,110)

20180103-1連寫數整除
給一個 正整數 p , 然後找一個最小的正整數n,數123…n串成的數字x使得 p 整除 x
In1.txt
3
2
6
8
In2.txt
3
7
15
17

Out.txt
2
2
6

11
5
21

12被2整除
12被6整除
123456可被8整除

1234567891011才能被7整除
12345可被15整除
123456789101112131415161718192021才被17整除

同餘  (a*b+c) Mod d = ( (a mod d) * b + c ) Mod d

20180103-2分數四則
輸入 a|b㊉c|d其中㊉是運算符號,可以是 + - * / 其中之一, a,b,c,d皆為不為負的整數,可能為0
   若b,d則輸出「除0錯誤」若運算為 / 且c為0亦輸出「除0錯誤」,運算結果若分子絕對值大於等於分母,輸出為帶分數型式(與分數部份空1格),若整除則不印分數部份,分數的部份化為最簡式,負號在最左方

In1.txt
3
3|2+5|4
2|3-14|4
2|3*6|4
In2.txt
3
2|3/4|5
5|3+7|0
4|5/0|2

Out.txt
2 3|4
-2 5|6
1

5|6
除0錯誤
除0錯誤
註:輸入與輸出的分子、分母間之直條 | 代表,與除號 / 有別
2與3|4之間空1格
負號在最左方
整除只印出整數部份





2018年1月1日 星期一

To Z2A 程式選訓(1227-4,1227-5)

1227-4_撲克21點(參考解)
輸入範例:
【in1.txt】
3
0,2,6
13,10,11
27,36,23
【in2.txt】
3
26,42,8
11,25,30
39,21,22
輸出範例:
【out.txt】
21
21
Bom

14
Bom
20
輸出說明:

索引:點數 … 
0:1 1:3 2:7 21      11+ 3+ 7 = 21
0:1 1:10 2:10 21    1 +10+10 = 21
0:2 1:10 2:10 Bom  2 + 10+10 = 22 Bom


0:1 1:4 2:9 14      1 + 4 + 9 = 14
0:10 1:10 2:5 Bom  10+10+ 5 = 25 Bom
0:1 1:9 2:10 20     1 + 9+10 = 20

程式碼:
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Hide()
        FileOpen(1, "in1.txt", OpenMode.Input)
        FileOpen(2, "in2.txt", OpenMode.Input)
        FileOpen(3, "out.txt", OpenMode.Output)
        For fn = 1 To 2
            If fn = 2 Then PrintLine(3)
            Dim n As Short = LineInput(fn)
            For k = 1 To n
                Dim s = LineInput(fn)
                PrintLine(3, fxx(s))
            Next
        Next
        End
    End Sub
    Function fxx(ByVal s As String) As String
        fxx = ""
        Dim dat() = s.Split(",")
        Dim sum As Integer = 0
        Dim ace As Boolean = False
        For i = 0 To 2
            Dim pt As Integer = dat(i) Mod 13 + 1
            If pt > 10 Then pt = 10
            '  Print(3, i & ":" & pt & " ")
            sum += pt
            If pt = 1 Then ace = True
        Next
        If ace And sum <= 11 Then sum += 10
        If sum > 21 Then Return "Bom" Else Return sum
    End Function
End Class

1227-5_大數加乘(參考解)
大數相加或大數相乘:兩個正整數a,b中間一個+或*,算出其結果,{若0}<=a,b<1050
輸入範例:
【in1.txt】
3
12345+98765432123456789
56*89
7995979239752398752987925925225252*0
【in2.txt】
3
567+433
2147483648*7487812485248974848
0+0
輸出範例:
【out.txt】
98765432123469134
4984
0

1000
16079954871362414694843285504
0
輸出說明:




乘0印出一個0




0+0也是0
程式碼:
Public Class Form1
    Const MaxN As Integer = 50
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Hide()
        FileOpen(1, "in1.txt", OpenMode.Input)
        FileOpen(2, "in2.txt", OpenMode.Input)
        FileOpen(3, "out.txt", OpenMode.Output)
        For fn = 1 To 2
            If fn = 2 Then PrintLine(3)
            Dim n As Short = LineInput(fn)
            For k = 1 To n
                Dim s = LineInput(fn)
                PrintLine(3, fxx(s))
            Next
        Next
        End
    End Sub
    Sub s2n(ByVal xs As String, ByRef x() As Integer, ByRef xn As Integer)
        '將數字串 倒轉為 陣列
        xn = xs.Length
        Dim i, j As Integer
        For i = xn To 1 Step -1
            x(j) = Mid(xs, i, 1)
            j += 1
        Next
        cut0(x, xn)
    End Sub
    Sub cut0(ByRef x() As Integer, ByRef xn As Integer)
        Do While xn > 0 AndAlso x(xn - 1) = 0
            xn -= 1
        Loop
    End Sub
    Function fxx(ByVal s As String) As String
        fxx = ""
        Dim a(MaxN), b(MaxN), c(MaxN + MaxN) As Integer  '會清為零,若只宣告一次需記得清
        Dim an, bn, cn As Integer
        Dim p As Integer = InStr(s, "+")
        If p > 0 Then
            s2n(Mid(s, 1, p - 1), a, an)
            s2n(Mid(s, p + 1), b, bn)
            big_add(a, an, b, bn, c, cn)
        Else
            p = InStr(s, "*")
            s2n(Mid(s, 1, p - 1), a, an)
            s2n(Mid(s, p + 1), b, bn)
            big_mul(a, an, b, bn, c, cn)
        End If
        fxx = big_print(c, cn)
    End Function
    Sub big_add(ByVal x() As Integer, ByVal xn As Integer, ByVal y() As Integer, ByVal yn As Integer, ByRef z() As Integer, ByRef zn As Integer)
        ' PrintLine(3, big_print(x, xn) & " add " & big_print(y, yn))
        zn = Math.Max(xn, yn)
        For i = 0 To zn - 1
            z(i) = x(i) + y(i)
        Next
        For i = 0 To zn - 1
            If z(i) >= 10 Then
                z(i + 1) += 1
                z(i) -= 10
            End If
        Next
        If z(zn) <> 0 Then zn += 1
    End Sub
    Sub big_mul(ByVal x() As Integer, ByVal xn As Integer, ByVal y() As Integer, ByVal yn As Integer, ByRef z() As Integer, ByRef zn As Integer)
        '  PrintLine(3, big_print(x, xn) & " mul " & big_print(y, yn))
        zn = xn + yn
        For i = 0 To xn - 1
            For j = 0 To yn - 1
                z(i + j) += x(i) * y(j)
            Next
        Next
        For i = 0 To zn - 1
            If z(i) >= 10 Then
                z(i + 1) += z(i) \ 10
                z(i) = z(i) Mod 10
            End If
        Next
        cut0(z, zn)
    End Sub
  
    Function big_print(ByVal x() As Integer, ByVal xn As Integer) As String
        Dim bp As String = ""
        If xn = 0 Then Return "0"
        For i = xn - 1 To 0 Step -1
            bp &= x(i)
        Next
        Return bp
    End Function
End Class