置頂

我的 VPython 教學文件 (HackMD 版本)

VPython 教學文件目錄 安裝及測試 基本語法 等速度直線運動 自由落下 終端速度 水平抛射 使用For迴圈計算水平抛射資料 斜向抛射 圓周運動 簡諧運動 單擺 木塊彈簧系統分離 重力及簡諧 行星運動 相疊木塊 雙重簡諧運動 一維彈性碰撞 ...

熱門文章

2025年9月30日 星期二

ZeroJudge 解題筆記:e698. OREOREO!

作者:王一哲
日期:2025年9月30日


ZeroJudge 題目連結:e698. OREOREO!

解題想法


我先計算 O 的部分較寬及 RE 的部分較寬兩種狀況下,分別要印出的 O 及 RE 的字串。接下來讀取 n 塊餅乾的組成方式,依序輸出每一塊餅乾對應的形狀。

Python 程式碼


使用時間約為 28 ms,記憶體約為 3.8 MB,通過測試。
import sys

for line in sys.stdin:
    w1, h1 = map(int, line.split())
    w2, h2 = map(int, sys.stdin.readline().split())
    c1, c2 = sys.stdin.readline().split()
    if w1 > w2:  # O 的部分較寬
        O = c1*w1
        RE = " "*((w1-w2)//2) + c2*w2
    else:  # RE 的部分較寬
        O = " "*((w2-w1)//2) + c1*w1
        RE = c2*w2
    n = int(sys.stdin.readline())  # 接下來有 n 塊餅乾
    for _ in range(n):  # 執行 n 次
        cookie = sys.stdin.readline().strip()  # 餅乾的組成
        i = 0  # 從 cookie 讀取資料用的索引值
        while i < len(cookie):  # 如果 i 還沒有出界時繼續執行
            if cookie[i] == "O":  # 如果是 O
                for _ in range(h1): print(O)  # 印出 h1 行的 O
                i += 1  # i 加 1
            elif cookie[i] == "R":  # 如果是 RE
                for _ in range(h2): print(RE)  # 印出 h2 行的 RE
                i += 2  # i 加 2
        print()  # 跑完一塊餅乾要換行


2025年9月29日 星期一

ZeroJudge 解題筆記:e623. 2. PPAP

作者:王一哲
日期:2025年9月29日


ZeroJudge 題目連結:e623. 2. PPAP

解題想法


先用一個 while 迴圈,計算序號 n 是第 m 輪領到東西,計算時每一輪會將 n 減去這一輪的數量。跑完 while 迴圈之後,如果 n 等於 0,代表是第 m 輪的最後一個人,印出 Pineapple pen; 反之進到下一輪,先將 m 加 1,計算 n 對 m 取整數除法的結果,輸出對應的物品名稱。

Python 程式碼


使用時間約為 46 ms,記憶體約為 3.3 MB,通過測試。
n = int(input())  # 編號
m = 0  # 第 m 輪
s = 0  # 第 m 輪的數量,每次加 4
while n >= s+4:  # 如果 n 的數量大於等於 s+4,還有下一輸,繼續執行
    m += 1; s += 4  # m 加 1;s 加 4
    n -= s  # n 減去 s

if n == 0:  # 剛好是第 m 輪的最後一個人
    print("Pineapple pen")  # 印出 Pineapple pen
else:  # 要再到下一輪
    m += 1  # m 加 1
    if n%m == 0: n -= 1
    item = n // m
    if item == 0: print("Pen")
    elif item == 1: print("Pineapple")
    elif item == 2: print("Apple")
    else: print("Pineapple pen")


2025年9月28日 星期日

ZeroJudge 解題筆記:e622. 3. 虛擬寵物大師 (Master)

作者:王一哲
日期:2025年9月28日


ZeroJudge 題目連結:e622. 3. 虛擬寵物大師 (Master)

解題想法


我另外寫兩個函式,函式 ivcp 輸入 iv 值,回傳升級時增加的 cp 值;函式 upgrade 輸入原有的星塵沙子數量 star,iv 值、原來的 cp 值,計算升級後的 cp 值。

Python 程式碼


使用時間約為 38 ms,記憶體約為 3.4 MB,通過測試。
# 輸入 iv 值,回傳升級時增加的 cp 值
def ivcp(iv):
    if 0 <= iv <= 29: return 10
    elif 30 <= iv <=39: return 50
    elif 40 <= iv <= 45: return 100

# 輸入原有的星塵沙子數量 star,iv 值、原來的 cp 值,計算升級後的 cp 值
def upgrade(star, iv, cp):
    while star >= 1000:
        star -= 1000
        cp += ivcp(iv)
    return cp

# 解題過程
n, s = map(int, input().split())  # 寵物數量 n,原有的星塵沙子數量 s
imax, idx = 0, 0  # 升級後最高的 cp 值及寵物編號
for i in range(1, n+1):  # 讀取 n 行資料
    c, v = map(int, input().split())  # 讀取原來的 cp 值、iv 值
    re = upgrade(s, v, c)  # 呼叫 upgrade,代入 s, v, c,計算升級後的 cp 值
    if re > imax:  # 如果 re 大於 imax
        imax = re  # 更新 imax
        idx = i  # 更新 idx
print(f"{idx:d} {imax:d}")  # 印出答案


2025年9月27日 星期六

ZeroJudge 解題筆記:e621. 1. 免費停車 (Free Parking)

作者:王一哲
日期:2025年9月27日


ZeroJudge 題目連結:e621. 1. 免費停車 (Free Parking)

解題想法


這題應該是多行測資,但是題目沒有說清楚。讀取測資中的 A、B、C 三個數字之後,用 for 迴圈跑 i = A-1 到 i = B-1,當 i 不能被 C 整除就加入答案之中。

Python 程式碼


使用時間約為 41 ms,記憶體約為 3.8 MB,通過測試。
import sys

for line in sys.stdin:
    N = int(line)
    for _ in range(N):
        A, B, C = map(int, input().split())
        ans = []
        for i in range(A+1, B):
            if i%C != 0: ans.append(i)
        if ans: print(*ans)
        else: print("No free parking spaces.")


2025年9月26日 星期五

ZeroJudge 解題筆記:e494. 無窮級數之和(二)

作者:王一哲
日期:2025年9月26日


ZeroJudge 題目連結:e494. 無窮級數之和(二)

解題想法


這題考數學及大數運算,所以我只有寫 Python 版本。公式解 $$ \frac{1}{2} + \frac{1}{3} + \frac{1}{5} + \frac{1}{7} + \dots + \frac{1}{p} = \ln(\ln p) + M = \ln(\ln p) + 0.2614972128476427837554268386 $$ 由於輸出的小數位數很多,甚至要用到 decimal 函式庫的浮點數物件 Decimal 才行。

Python 程式碼


使用時間約為 50 ms,記憶體約為 4 MB,通過測試。
import sys, decimal

def solve(n):
    decimal.getcontext().prec = 1000  # 設定小數位數
    p = decimal.Decimal(n)  # 用 Decimal 格式的浮點數
    if p == decimal.Decimal(2):  # 特例,n 等於 2,回傳 0.5
        return decimal.Decimal('0.5')
    # 公式解,ln(ln(n)) + M
    ln_ln_p = p.ln().ln()
    M = decimal.Decimal('0.2614972128476427837554268386')
    return round(ln_ln_p + M, 3)

for line in sys.stdin:
    print(f"{solve(decimal.Decimal(line)):.3f}")


2025年9月25日 星期四

ZeroJudge 解題筆記:e484. 我是優質學生

作者:王一哲
日期:2025年9月25日


ZeroJudge 題目連結:e484. 我是優質學生

解題想法


這題要判斷輸入的數字是否為 2 到 10000 之間的質數,由於輸入只有一行,不要建質數表,直接判斷這個數是否為質數就好。

Python 程式碼


使用時間約為 18 ms,記憶體約為 3.3 MB,通過測試。
def is_prime(n):  # 判斷是否為質數
    if n <= 1: return False  # 特例,小於等於1,回傳 False
    if n == 2 or n == 3: return True  # 特例,等於 2 或 3,回傳 True
    if n%2 == 0 or n%3 == 0: return False  # 特例,可以被 2 或 3 整除,回傳 False
    for i in range(5, int(n**0.5)+1, 6):  # 依序檢查 5 ~ sqrt(n),每次加 6
        if n%i == 0 or n%(i+2) == 0:  # 如果可以被 i 或 i+2 整除,回傳 Fasle
            return False
    return True  # 最後回傳 True

print("yes" if is_prime(int(input())) else "no")


2025年9月24日 星期三

ZeroJudge 解題筆記:e470. 無窮級數之和(一)

作者:王一哲
日期:2025年9月24日


ZeroJudge 題目連結:e470. 無窮級數之和(一)

解題想法


這題考數學,當 $n$ 很大時,有近似公式 $$ \sum_{i=1}^{n} \frac{1}{i} = \ln n + \gamma + \frac{1}{2n} $$ 其中 $\gamma = 5772156649$。

Python 程式碼


使用時間約為 18 ms,記憶體約為 3.3 MB,通過測試。
import sys, math

def harmonic_number(n):
    if n <= 20:  # 如果 n 小於等於 20,直接用迴圈計算
        isum = 0
        for i in range(1, n+1): isum += 1/i
        return isum
    gamma = 0.5772156649  # 反之,代近似公式
    return math.log(n) + gamma + 1.0 / (2 * n)

for line in sys.stdin:
    print(f"{harmonic_number(int(line)):.3f}")


2025年9月23日 星期二

ZeroJudge 解題筆記:e447. queue 練習

作者:王一哲
日期:2025年9月23日


ZeroJudge 題目連結:e447. queue 練習

解題想法


這題就是考 queue 的操作,在 Python 要引入 collections 函式庫的 deque,在 C++ 要引入 queue 或是 deque 都可以。

Python 程式碼


使用時間約為 0.5 s,記憶體約為 6.6 MB,通過測試。
from collections import deque

n = int(input())
arr = deque()
for _ in range(n):
    line = list(map(int, input().split()))
    if len(line) == 1:
        if line[0] == 2:
            if arr: print(arr[0])
            else: print(-1)
        elif line[0] == 3 and arr: arr.popleft()
    else:
        arr.append(line[1])


2025年9月22日 星期一

ZeroJudge 解題筆記:e446. 排列生成

作者:王一哲
日期:2025年9月22日 第二版:2026年9月10日,重寫 dfs 窮舉的程式碼


ZeroJudge 題目連結:e446. 排列生成

解題想法


這題不論用 Python 還是 C++ 都可以用遞迴窮舉所有的排列方式。在 Python 也可以用 itertools.permutaions,在 C++ 也可以用 next_permutation。但主要的困難之處是輸出速度,要加速才能過關。

2026年9月10日更新,重寫 dfs 窮舉的程式碼


Python,使用時間約為 8.6 s,記憶體約為 9.6 MB,通過測試。
def solve():
    import sys

    data = sys.stdin.read().split()
    ptr = 0
    while ptr < len(data):
        n = int(data[ptr])
        ptr += 1

        def dfs(path, visited):
            if len(path) == n:
                res = " ".join(map(str, path)) + "\n"
                sys.stdout.write(res)
                return
            
            for i in range(1, n+1):
                if visited[i]: continue
                visited[i] = True
                path.append(i)
                dfs(path, visited)
                visited[i] = False
                path.pop()
        # End of DFS
        dfs([], [False] * (n+1))

if __name__ == "__main__":
    solve()


C++,使用時間約為 2.9 s,記憶體約為 3.9 MB,通過測試。
#include <cstdio>
#include <vector>
using namespace std;

int n;

void dfs(vector<int>& path, vector<bool>& visited) {
    if ((int)path.size() == n) {
        for(int i = 0; i < n; i++) {
            printf("%d", path[i]);
            if (i == n-1) printf("\n");
            else printf(" ");
        }
        return;
    }

    for(int i = 1; i <= n; i++) {
        if (visited[i]) continue;
        visited[i] = true;
        path.push_back(i);
        dfs(path, visited);
        visited[i] = false;
        path.pop_back();
    }
}

int main() {
    while(scanf("%d", &n) != EOF) {
        vector<int> path;
        vector<bool> visited (n+1, false);
        dfs(path, visited);
    }
    return 0;
}


Python 程式碼


窮舉,用 print 輸出,超時。
def solve(arr, n, used):
    if len(arr) == n:
        print(*arr)
        return
    for i in range(1, n+1):
        if i in used: continue
        used.add(i)
        arr.append(i)
        solve(arr, n, used)
        used.remove(i)
        arr.pop()
    return

solve([], int(input()), set())

窮舉,用 sys.stdout.write 輸出,超時。
import sys

def solve(arr, n, used):
    if len(arr) == n:
        s = " ".join(map(str, arr)) + "\n"
        sys.stdout.write(s)
        return
    for i in range(1, n+1):
        if i in used: continue
        used.add(i)
        arr.append(i)
        solve(arr, n, used)
        used.remove(i)
        arr.pop()
    return

solve([], int(sys.stdin.readline()), set())

用 itertools.permutations,用 sys.stdout.write 最後再一次輸出所有結果,最後一筆測資超出記憶體上限。
import sys, itertools

result = []
n = int(sys.stdin.readline())
nums = list(range(1, n+1))
for perm in itertools.permutations(nums):
    s = " ".join(map(str, perm))
    result.append(f"{s}\n")
sys.stdout.write("".join(result))

用 itertools.permutations,用 sys.stdout.write 逐行輸出結果。使用時間約為 12.3 s,記憶體約為 3.4 MB,通過測試。
import sys, itertools

n = int(sys.stdin.readline())
nums = list(range(1, n+1))
for perm in itertools.permutations(nums):
    s = " ".join(map(str, perm)) + "\n"
    sys.stdout.write(s)


2025年9月21日 星期日

ZeroJudge 解題筆記:e420. 灰姑娘的新衣

作者:王一哲
日期:2025年9月20日


ZeroJudge 題目連結:e420. 灰姑娘的新衣

解題想法


我用字典 color_idx 儲存各種顏色對應的衣服編號,另一個字典 idx_color 儲存各種衣服編號有的顏色,顔色不重複。最後再計算所有的組合數,輸出最多顔色的衣服,輸出完美搭配的顔色。

Python 程式碼


使用時間約為 22 ms,記憶體約為 3.7 MB,通過測試。
import sys
from collections import defaultdict

color_idx = defaultdict(list)  # 各種顏色對應的衣服編號,可重複
idx_color = defaultdict(set)  # 各種衣服編號有的顏色,不重複
cnt = 0  # 衣服編號
for line in sys.stdin:
    line = line.strip()  # 刪除最後的 \n
    cnt += 1  # 衣服編號加 1
    color_idx[line].append(cnt)  # 顏色 line 有的編號加上 cnt
    idx_color[cnt].add(line)  # 編號 cnt 有的顏色加上 line
    for s in sys.stdin:
        s = s.strip()  # 讀取一行字串,刪除最後的 \n
        if s == "@" or s == "#": break  # 讀到 # 或 @,中止迴圈
        color_idx[s].append(cnt)  # 顏色 s 有的編號加上 cnt
        idx_color[cnt].add(s)  # 編號 cnt 有的顏色加上 s,不重複
comb = 1  # 組合數
for v in idx_color.values(): comb *= len(v)
print(comb)
most_color = []
n = len(idx_color)  # 編號數量
perfect = []
imax = max([len(v) for v in color_idx.values()])
for k, v in color_idx.items():
    if len(v) == imax:
        most_color.append(k)
    if len(set(v)) == n:
        perfect.append(k)
print(",".join(sorted(most_color)))
print(",".join(sorted(perfect)))