一个最无脑直给的暴力计算 SG 函数解法,每个日期向其合法的前驱日期连边,递推计算所有日期的 SG 函数即可。赛时没敢交,发现能过~

from datetime import datetime, timedelta

start = datetime(2000, 1, 1)
end = datetime(2024, 8, 1)
tot = (end - start).days + 1

def date_to_int(date):
    return (date - start).days

def int_to_date(value):
    return start + timedelta(days=value)

def is_valid_date(year, month, day):
    try:
        date = datetime(year, month, day)
        if start <= date <= end: return True
        return False
    except:
        return False

def MEX(H):
    i = 0
    while True:
        if i not in H:
            return i
        i += 1

def cal_SG():

    g = [[] for _ in range(tot)]
    in_deg = [0] * tot

    for i in range(1, tot):
        cur = int_to_date(i)
        cur_y, cur_m, cur_d = cur.year, cur.month, cur.day
        # 减去一天
        pre1 = cur - timedelta(days=1)
        if pre1 >= start:
            pre1_int = date_to_int(pre1)
            g[i].append(pre1_int)
            in_deg[pre1_int] += 1
        # 减去一月
        pre2_y, pre2_m, pre2_d = cur_y, cur_m - 1, cur_d
        if pre2_m < 1:
            pre2_m = 12
            pre2_y = cur_y - 1
        if is_valid_date(pre2_y, pre2_m, pre2_d):
            pre2 = datetime(pre2_y, pre2_m, pre2_d)
            pre2_int = date_to_int(pre2)
            g[i].append(pre2_int)
            in_deg[pre2_int] += 1
            
    # 从最终状态开始,递推计算 SG 函数
    sg = [0] * tot
    sg_set = defaultdict(set)
    q = deque([tot - 1])
    
    while q:
        node = q.popleft()
        for pre in g[node]:
            sg_set[pre].add(sg[node])
            in_deg[pre] -= 1
            if in_deg[pre] == 0:
                sg[pre] = MEX(sg_set[pre])
                q.append(pre)

    return sg

if __name__ == '__main__':
    # 预处理 SG 函数
    sg = cal_SG()
    T = ii()
    for _ in range(T):
        y, m, d = mii()
        v = sg[date_to_int(datetime(y, m, d))]
        # 当 SG 函数不为 0 时有必胜策略
        if v != 0:
            print("YES")
        else:
            print("NO")