結果

問題 No.653 E869120 and Lucky Numbers
ユーザー qwewe
提出日時 2025-05-14 12:57:38
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 70 ms / 2,000 ms
コード長 6,631 bytes
コンパイル時間 140 ms
コンパイル使用メモリ 82,732 KB
実行使用メモリ 80,700 KB
最終ジャッジ日時 2025-05-14 12:59:13
合計ジャッジ時間 2,491 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 31
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys

# Set a higher recursion depth limit if needed, although this solution is iterative.
# sys.setrecursionlimit(21000) 

def solve():
    # Read the input number p as a string
    p_str = sys.stdin.readline().strip()
    N = len(p_str)
    
    # Handle edge case: If p is an empty string (based on constraints p >= 1, N should be >= 1)
    # If N=0, p is empty string or 0. If p=0, it cannot be represented as sum of two positive lucky numbers.
    if N == 0:
         print("No") 
         return

    # Convert the string p into a list of digits. Reverse it to process from right to left (units digit first).
    # p_digits[i] will be the i-th digit from the right (0-indexed).
    p_digits = [int(d) for d in p_str]
    p_digits.reverse() 

    # Initialize DP table using a list of sets.
    # dp[i] will store the set of reachable states after processing column i-1 (before processing column i).
    # Each state is a tuple: (carry_in, a_ended, b_ended, a_non_zero, b_non_zero)
    # carry_in: The carry coming into column i from column i-1. Can be 0 or 1.
    # a_ended: Boolean flag, True if number 'a' has already terminated (all subsequent digits must be 0).
    # b_ended: Boolean flag, True if number 'b' has already terminated.
    # a_non_zero: Boolean flag, True if 'a' has had at least one non-zero digit (6 or 7) assigned so far.
    # b_non_zero: Boolean flag, True if 'b' has had at least one non-zero digit (6 or 7) assigned so far.
    # The maximum number of states per column is 2*2*2*2*2 = 32. Storing states in a set automatically handles duplicates.
    dp = [set() for _ in range(N + 1)] 
    
    # Base case: Before processing any digits (at column 0), the carry is 0. 
    # Both numbers 'a' and 'b' are considered active (not ended, so za=False, zb=False).
    # Initially, neither 'a' nor 'b' has been assigned a non-zero digit (so nza=False, nzb=False).
    dp[0].add((0, False, False, False, False)) 

    # Iterate through the columns, corresponding to the digits of p from right to left (0 to N-1).
    for i in range(N): 
        
        # Optimization: If dp[i] is empty, it means no valid assignment of digits
        # could produce the prefix of p processed so far. Thus, no solution is possible.
        if not dp[i]: 
            break 

        # Get the current digit of p we need to match.
        current_p_digit = p_digits[i]

        # Explore transitions from each reachable state at column i.
        for state in dp[i]:
            # Unpack the current state tuple
            c, za, zb, nza, nzb = state
            
            # Determine the possible digits (da) for number 'a' at the current column i.
            # If 'a' has already ended (za is True), the only possible digit is 0.
            # If 'a' is still active (za is False), the possible digits are 6, 7, or 0.
            # Choosing 0 when za is False signifies that 'a' terminates at this point (ends just before this column).
            possible_da = [0] if za else [6, 7, 0]

            # Determine the possible digits (db) for number 'b' similarly.
            possible_db = [0] if zb else [6, 7, 0]

            # Iterate through all valid combinations of digits (da, db) for the current column i.
            for da in possible_da:
                 # The check `if za and da != 0: continue` is implicitly handled by how possible_da is generated.
                 # If za is True, possible_da is only [0]. So da is always 0.
                 
                 for db in possible_db:
                    # Similarly, `if zb and db != 0: continue` is implicitly handled.
                    
                    # Calculate the sum for the current column: digit_a + digit_b + carry_in
                    current_sum = da + db + c
                    
                    # Check if the unit digit of the sum matches the required digit of p for this column.
                    if current_sum % 10 == current_p_digit:
                        
                        # Calculate the carry for the next column (i+1).
                        next_c = current_sum // 10
                        
                        # The carry can only be 0 or 1 because max sum is 7+7+1 = 15.
                        # If next_c > 1, it implies an impossible situation or error. We can skip.
                        if next_c > 1: continue 

                        # Determine the state flags for the next column (i+1):
                        
                        # next_za: 'a' ends if it was already ended (za=True) OR if the chosen digit da is 0.
                        next_za = za or (da == 0) 
                        
                        # next_zb: 'b' ends if it was already ended (zb=True) OR if the chosen digit db is 0.
                        next_zb = zb or (db == 0)

                        # next_nza: 'a' is considered non-zero if it was already non-zero (nza=True) OR if the chosen digit da is non-zero (6 or 7).
                        next_nza = nza or (da != 0)
                        
                        # next_nzb: 'b' is considered non-zero if it was already non-zero (nzb=True) OR if the chosen digit db is non-zero (6 or 7).
                        next_nzb = nzb or (db != 0)
                        
                        # Add the computed next state to the set of reachable states for column i+1.
                        dp[i+1].add((next_c, next_za, next_zb, next_nza, next_nzb))

    # After iterating through all N columns (0 to N-1):
    # The final states are stored in dp[N]. These states represent the status after processing the most significant digit p_{N-1}.
    # A valid solution requires finding a state in dp[N] that meets the problem criteria.
    found_solution = False
    for state in dp[N]:
        c, za, zb, nza, nzb = state
        # Check for the conditions of a valid solution:
        # 1. The final carry (carry out of the last processed column N-1, which is carry *into* column N) must be 0.
        #    This ensures the sum matches p exactly and doesn't require an extra digit.
        # 2. Both constructed numbers 'a' and 'b' must be non-zero (positive). This is tracked by nza and nzb flags.
        #    A lucky number must be positive by definition ("0 is not a lucky number").
        if c == 0 and nza and nzb:
             found_solution = True
             break # Found a valid solution, no need to check further states.

    # Output the final result based on whether a valid solution was found.
    if found_solution:
        print("Yes")
    else:
        print("No")

# Call the solve function to run the logic.
solve()
0