日期:2026年9月2日
ZeroJudge 題目連結:s216.三仙鬥法 (Competition)
題目 pdf 檔連結:三仙鬥法 (Competition)
解題想法
題目是多筆測資。每筆測資第一列是一個整數 $R$,代表共有 $R$ 輪比賽;第二列有 3 個正整數 $a, b, c ~(1 \leq a, b, c \leq 10^{18})$,代表 3 個學院派出的選手靈氣值。每回合行動時,靈氣值最低的選手恢復 1 點靈氣值,較高的 2 個選手各減 1 點靈氣值;如果有多個選手的靈氣值最低,每個選手皆有相同的機率恢復 1 點靈氣值;不斷執行直到同時有 2 個選手的靈氣值歸零,此時靈氣值還沒有歸零的選手獲勝。題目要回傳每回合獲勝選手代表的學院,A、B、C 其中一個字母;如果三個學院獲勝機率相等,回傳 A B C。
由於這題的靈氣值很大,如果真的模擬比賽過程一定會超時,要找數學規律解題。由於 3 個選手其中 2 個的靈氣值減 1,另 1 個選手靈氣值加 1,所有選手的靈氣值都會加 1 或減 1。如果其中 2 個選手的靈氣值為來是偶數、另 1 個選手的靈氣值原為奇數,經過 1 個回合之後 2 個人的靈氣值同時變為奇數、另 1 個人的靈氣值變為偶數,因此只有這 2 個人的靈氣值同時歸零才會結束這輪比賽,一定是另 1 個選手獲勝。如果 3 個選手的靈氣值皆為偶數或奇數,經過多個回合之後 3 個人的靈氣值會相等,獲勝機率相同,答案是 A B C。因此這題不需要模擬比賽過程,只要用 $a, b, c$ 的奇偶性就可以直接輸出答案。
Python 程式碼
使用時間約為 0.1 s,記憶體約為 11.4 MB,通過測試。
def solve():
import sys
def get_tokens():
for line in sys.stdin:
for token in line.split():
yield int(token)
tokens = get_tokens()
result = []
while True:
try:
R = next(tokens)
except StopIteration:
break
for _ in range(R):
a = next(tokens) % 2
b = next(tokens) % 2
c = next(tokens) % 2
if a == b == c:
result.append("A B C\n")
elif b == c:
result.append("A\n")
elif a == c:
result.append("B\n")
elif a == b:
result.append("C\n")
sys.stdout.write("".join(result))
if __name__ == "__main__":
solve()
C++ 程式碼
$a, b, c$ 要用 long long 避免溢位,使用時間約為 48 ms,記憶體約為 1.6 MB,通過測試。
#include <cstdio>
int main() {
int R;
while(scanf("%d", &R) != EOF) {
long long a, b, c;
for(int r = 0; r < R; r++) {
scanf("%lld %lld %lld", &a, &b, &c);
a %= 2; b %= 2; c %= 2;
if (a == b && b == c) {
puts("A B C");
} else if (a == b) {
puts("C");
} else if (b == c) {
puts("A");
} else if (a == c) {
puts("B");
}
}
}
return 0;
}
C 語言程式碼
$a, b, c$ 要用 long long 避免溢位,使用時間約為 50 ms,記憶體約為 1.6 MB,通過測試。
#include <stdio.h>
int main() {
int R;
while(scanf("%d", &R) != EOF) {
long long a, b, c;
for(int r = 0; r < R; r++) {
scanf("%lld %lld %lld", &a, &b, &c);
a %= 2; b %= 2; c %= 2;
if (a == b && b == c) {
puts("A B C");
} else if (a == b) {
puts("C");
} else if (b == c) {
puts("A");
} else if (a == c) {
puts("B");
}
}
}
return 0;
}
沒有留言:
張貼留言