結果
問題 |
No.3024 全単射的
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:16:18 |
言語 | PyPy3 (7.3.15) |
結果 |
RE
|
実行時間 | - |
コード長 | 4,340 bytes |
コンパイル時間 | 343 ms |
コンパイル使用メモリ | 82,688 KB |
実行使用メモリ | 65,792 KB |
最終ジャッジ日時 | 2025-05-14 13:17:46 |
合計ジャッジ時間 | 3,165 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | RE * 22 |
ソースコード
import sys import itertools from math import isclose # Epsilon for floating-point comparison EPS = 1e-9 # Memoization dictionary: maps tuple(sorted_numbers) -> set(possible_values) memo = {} def get_possible_values(nums): """ Recursively calculates all possible values obtainable from the tuple 'nums' using +, -, *, /. Uses memoization. Input: tuple of numbers. Output: set of possible float values. """ # Ensure canonical representation for memoization key # Convert to tuple and sort if not already done (should be done before calling usually) # Here we assume the input 'nums' itself will be used as key directly or indirectly # after sorting within the caller or callee. Let's sort here for safety. # Convert potential ints to floats early nums_float = tuple(float(x) for x in nums) # Sort for canonical memoization key key = tuple(sorted(nums_float)) if key in memo: return memo[key] n = len(key) if n == 1: return {key[0]} results = set() # Split the 'key' tuple into two non-empty sub-tuples # Iterate through possible sizes of the first subset (from 1 to n-1) for i in range(1, n): # Generate combinations of indices for the first subset for indices1 in itertools.combinations(range(n), i): sub1 = tuple(key[j] for j in indices1) sub2 = tuple(key[j] for j in range(n) if j not in indices1) # Recursively get values for sub-problems # The recursive call will handle sorting and memoization for sub-problems values1 = get_possible_values(sub1) values2 = get_possible_values(sub2) # Combine results from sub-problems for v1 in values1: for v2 in values2: results.add(v1 + v2) results.add(v1 - v2) results.add(v2 - v1) results.add(v1 * v2) if not isclose(v2, 0.0, abs_tol=EPS): results.add(v1 / v2) if not isclose(v1, 0.0, abs_tol=EPS): results.add(v2 / v1) memo[key] = results return results # --- Main Execution --- # Read input N = int(sys.stdin.readline()) A = list(map(int, sys.stdin.readline().split())) all_nums = tuple(A) found_equation = False # Iterate through all possible ways to partition A into two non-empty subsets # We only need to check partitions where the first set has size 1 to N//2 # because partitioning into (Set1, Set2) is equivalent to (Set2, Set1). for i in range(1, N // 2 + 1): # Generate all subsets (indices) of size i for the first part (left side) for left_indices in itertools.combinations(range(N), i): left_set = tuple(all_nums[k] for k in left_indices) right_set = tuple(all_nums[k] for k in range(N) if k not in left_indices) # Calculate possible values for both sets # The function get_possible_values handles memoization internally # based on the sorted tuple of numbers. # Clear memoization for each top-level partition? # No, memoization should persist across partitions as subsets might overlap. possible_left_values = get_possible_values(left_set) possible_right_values = get_possible_values(right_set) # Check if there's any common value (within epsilon) # Optimization: Check if intersection is non-empty first for exact matches # if not possible_left_values.isdisjoint(possible_right_values): # found_equation = True # break # Check with tolerance for floats match_found_in_partition = False for val_l in possible_left_values: for val_r in possible_right_values: if isclose(val_l, val_r, abs_tol=EPS): match_found_in_partition = True break if match_found_in_partition: break if match_found_in_partition: found_equation = True break # Break from the inner loop (combinations) if found_equation: break # Break from the outer loop (sizes i) # Print the result if found_equation: print("YES") else: print("NO")