2024年1月12日 星期五

APCS 2024.01 m931. 1. 遊戲選角

         考試中常常用到排序,只是往往不會只是單純排序,有些時候,會需要在排序的資料裡面,添加一些不必要排序的資料,就像這題,表面是針對戰鬥力排名,但輸出的時候是要輸出攻擊力與防禦力,所以基本上的做法就是依序將[戰鬥力、攻擊力、防禦力]當成一筆資料塞入陣列之中,透過sort指令,因為系統預設的sort指令會先依第一個欄位排序,如果第一個欄位相同就繼續比第二個,以此類推。

        完整程式如下:

n = int(input())
p = []
for i in range(n):
    q,m = [int(i) for i in input().split()]
    p.append([q**2 + m**2 , q , m])
p.sort()

print(p[-2][1] , p[-2][2])

2024年1月11日 星期四

i025. 真因數和 (小 n)

         沒有太過分的求因數,小心避開當輸入為1、找因數的迴圈終點記得開根號處理,很多神奇的技巧如6n+1,6n-1,找因數的時候一次間隔兩個數....技巧都不需用上。

        以下附上完整程式碼:

def t():
    n = int(input())
    if n == 1:
        print(0)
        return
    p = int(n**0.5) + 1
    
    total = 0
    for i in range(1,p):
        if n % i == 0:
            j = n//i
            if j == i or j == n:
                total += i
            else:
                total += i + j
    print(total)
    
t()

f327. 刪除欄位

         這題就是單純的16進制轉換題,如果同樣的題目,是十進制出題,那是絕對的送分題,以十進制來看,假設收到三個char(a,b,c)需要我們將它組成一個百位數數字,那麼程式作法拆解下來就是total = a - char(0) ,再來是total = total * 10 + b - char(0) ,最後是total = total * 10 + c - char(0) ,數學式子去理解就是total = a * 100 + b * 10 + c,那麼將同樣概念運用在這題就沒問題了。

        以下附上完整程式:

d = input().split()

ft,st = 0,0
f,s = d
for i in range(len(f)):
    ft = ft * 26 +  (ord(f[i]) - ord('A')+1) 
for i in range(len(s)):
    st = st * 26 +  (ord(s[i]) - ord('A')+1) 
print(st - ft + 1)

2024年1月9日 星期二

k740. 楊輝三角形

        這題是標準的DP問題,扣除每一行的頭跟尾(都是1),每一行的資料都是由上一行的正上方與左上方提供。

        以下附上完整程式碼:

n = int(input())
d = [[1 for i in range(21)] for j in range(21)]

for i in range(1,n+1):
    for j in range(i):
        if j != 0 and j != i-1:
            d[i][j] = d[i-1][j] + d[i-1][j-1]
        print(d[i][j] , end = ' ')
    print()

m283. 螞蟻的擴散

         這是一題標準的DP題目,假設以dp[x][y]做為起點開始走,那麼從dp[x][y]走一步後,dp[x-1][y]跟dp[x][y-1],dp[x-1][y-1]這三個位置個會增加dp[x][y]/3的機率被走到,以此類推直到X或是Y軸為0,最後計算起點跟終點的比值即可。

        下列附上程式:

import math

def cal(x, y):
    # 初始化dp陣列
    dp = [[0] * 11 for _ in range(11)]
    
    # 設定起點的機率為1
    dp[x][y] = 1*3**(x+y)
    
    # 遞迴計算dp
    for i in range(x, 0, -1):
        for j in range(y, 0, -1):
            dp[i-1][j] += dp[i][j] / 3
            dp[i][j-1] += dp[i][j] / 3
            dp[i-1][j-1] += dp[i][j] / 3
    
    ans = int(dp[x][y] - dp[0][0])
    cc = math.gcd(int(ans), int(dp[x][y]))
    dp[x][y] //= cc
    ans //= cc
    print(str(ans) + "/" + str(dp[x][y]))
    # 將分數化簡
    '''common_factor = math.gcd(int(result), 81)
    result /= common_factor'''

try:
    while True:
        x,y = [int(i) for i in input().split()]
        cal(x,y)
except:
    pass

k862. 輩份比較

        假設B,C是A的祖先,D,E是A的子孫,F是E的子孫,如果我們先忽略輩分這件事情,單純從A點走到F,那就是一個單純的BFS就可以解決的事情,只要在BFS的基礎上,讓每個節點記錄自己的父輩與子孫輩的成員即可。





下列附上程式碼:


class Node:
    def __init__(self):
        self.father = []
        self.child = []
        self.dis = -99999999


s = set()
n = int(input())
d = {}
for i in range(n):
    c,f = input().split()
    if c not in d:
        d[c] = Node()
    if f not in d:
        d[f] = Node()
    d[c].father.append(f)
    d[f].child.append(c)
    
start,target = input().split()

d[start].dis = 0
p = [start]
keep = True
while keep:
    for i in p:
        for j in d[i].father:
            if j not in s:
                s.add(j)
                d[j].dis = d[i].dis-1
                p.append(j)
                if j == target:
                    keep = False
                    break
        for j in d[i].child:
            if j not in s:
                s.add(j)
                d[j].dis = d[i].dis+1
                p.append(j)
                if j == target:
                    keep = False
                    break
        if keep == False: break
print(d[target].dis)

2024年1月8日 星期一

m685. 三角形計數器

         辨別三角形相同的方式有很多,我們選其中一個方式來解題,假設兩個三角形,各三個邊由小到大分別是a,b,c  及  a1,b1,c1,如果a/b==a1/b1 and b/c == b1/c1 and c/a == c1/a1,那麼這兩個三角形及為相似三角形,最後用上set來濾掉重複的三角形即可。

n = int(input())
s = set()
for i in range(n):
    d = [int(i) for i in input().split()]
    d.sort()
    s.add(str(d[0]/d[1]) + str(d[1]/d[2]) + str(d[2]/d[0]))
print(len(s))

o079. 4. 最佳選擇

 題目描述: 給一個長度為 n 的正整數序列 a1,a2...an ,你可以執行多次操作 (包含 0 次),每次操作只能選擇這個序列的第一個或最後一個數字,再將這個數字從序列中刪除並自己搜集起來。 求滿足總和不超過 k 且搜集的數字奇數和偶數個數相同的條件下,所能搜集的數字總和最...