熱門文章

2026年2月14日 星期六

ZeroJudge 解題筆記:c069. 00602 - What Day Is It?

作者:王一哲
日期:2026年2月14日


ZeroJudge 題目連結:c069. 00602 - What Day Is It?

解題想法


將題目需要的功能分拆成以下的自訂函式
  1. is_leap_julian,用來判斷依據儒略曆閏年規則,輸入的年份是否為閏年。
  2. is_leap_gregorian,用來判斷依據格里曆閏年規則,輸入的年份是否為閏年。
  3. is_valid_date,檢查日期是否有效。
  4. get_day_of_week,計算指定日期是星期幾。


Python 程式碼


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

# 月份名稱對照表
month_names = ("", "January", "February", "March", "April", "May", "June",
               "July", "August", "September", "October", "November", "December")
# 每個月的天數 (非閏年)
month_days = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
# 星期名稱
weekday_names = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")

def is_leap_julian(year):
    """ 儒略曆閏年規則:能被4整除 """
    return year % 4 == 0

def is_leap_gregorian(year):
    """ 格里曆閏年規則:能被4整除且不被100整除,或者能被400整除 """
    return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)

def is_valid_date(month, day, year):
    """ 檢查日期是否有效 """
    # 月份小於 1 或大於 12,日期小於 1,年小於 1
    if month < 1 or month > 12 or day < 1 or year < 1: return False
    # 特殊情況:1752年9月的轉換,沒有9月3日 ~ 13日
    if year == 1752 and month == 9:
        if day == 2 or day == 14: return True
        if 2 < day < 14: return False
    # 該月份的天數
    max_day = month_days[month]
    if month == 2:  # 2月,是否為閏年
        if year < 1752:  # 採用儒略曆
            leap = is_leap_julian(year)
        else:  # 採用格里曆
            leap = is_leap_gregorian(year)
        if leap:  # 如果是閏年,有29天
            max_day = 29
    # 如果 day 小於等於 max_day 為 True,反之為 False
    return day <= max_day

def get_day_of_week(month, day, year):
    """計算指定日期是星期幾"""
    # 題目給定公元1年1月1日是星期六 (Sunday ~ Saturday 的編號分別為 0 ~ 6)
    total_days = 0  # 指定日期為公元1年1月1日之後第幾天
    # 計算從1年到(year-1)年的總天數
    for y in range(1, year):
        if y < 1752:
            leap = is_leap_julian(y)
        else:
            leap = is_leap_gregorian(y)
        total_days += 366 if leap else 365
    # 計算當年1月1日到當月1日的天數
    for m in range(1, month):
        if m == 2:
            if year < 1752:
                leap = is_leap_julian(year)
            else:
                leap = is_leap_gregorian(year)
            total_days += 29 if leap else 28
        else:
            total_days += month_days[m]
    # 加上當月的天數
    total_days += day - 1
    # 特殊調整:1752年9月轉換,橫跨1752年9月14日,要減11天
    if year > 1752 or (year == 1752 and month > 9) or (year == 1752 and month == 9 and day >= 14):
        total_days -= 11
    # 計算星期幾 (1年1月1日是星期六,即weekday=6)
    weekday = (total_days + 6) % 7
    return weekday

""" 主要的解題過程 """
for line in sys.stdin:
    parts = line.strip().split()
    if len(parts) != 3: continue  # 不合法的資料,理論上不會遇到
    month, day, year = map(int, parts)  # 月、日、年轉成整數
    if month == 0 and day == 0 and year == 0: break  # 中止迴圈的條件
    # 檢查日期是否有效
    if not is_valid_date(month, day, year):
        print(f"{month}/{day}/{year} is an invalid date.")
        continue
    # 獲取星期幾
    print(f"{month_names[month]} {day}, {year} is a {weekday_names[get_day_of_week(month, day, year)]}")


C++ 程式碼


使用時間約為 1 ms,記憶體約為 308 kB,通過測試。
#include <cstdio>

int main() {
    int n, m;
    while(scanf("%d %d", &n, &m) != EOF) {
        if (n == 0 && m == 0) break;
        long ans = 1;
        if (n-m < m) m = n-m;
        for(int i=1; i<=m; i++) ans = ans*(n-m+i)/i;
        printf("%ld\n", ans);
    }
    return 0;
}


沒有留言:

張貼留言