結果
問題 |
No.653 E869120 and Lucky Numbers
|
ユーザー |
![]() |
提出日時 | 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 |
ソースコード
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()