There are 3 levels, level 1/2/3 has number 1 to 50/100/200 on board to choose from Each number you choose, you get the corresponding points However, your opponent will choose all the factors of the number you choose, and get the points of each factor You can not choose numbers that are already assigned to a player You are only allow to choose the number if it has at least one factor not choosen If you can't choose anymore, the rest of the board goes to your opponent To make the challenge harder, there is a counter that starts with19/37/76inlevel1/2/3, eachtime you choose a number, the counter decreases by1 When it reaches 0, and the game will end, and the unassigned numbers will goto your opponent The challenge isalways solvable Player with highest score wins
from pwn import * import math def get_factors(num): factors = {1} for i in range(2, int(math.sqrt(num)) + 1): if num % i == 0: factors.add(i) factors.add(num // i) return factors def calculate_opponent_score(choice, assigned_numbers): factors = get_factors(choice) opponent_score = 0 for factor in factors: if factor not in assigned_numbers and factor != choice: opponent_score += factor return opponent_score def can_choose(num, assigned_numbers): factors = get_factors(num) for factor in factors: if factor not in assigned_numbers: return True return False def generate_priority_list(level): if level == 1: numbers = list(range(1, 51)) elif level == 2: numbers = list(range(1, 101)) else: numbers = list(range(1, 201)) prime_numbers = [num for num in numbers if is_prime(num)] composite_numbers = [num for num in numbers if not is_prime(num)] return prime_numbers + composite_numbers def is_prime(num): if num <= 1: return False for i in range(2, int(math.sqrt(num)) + 1): if num % i == 0: return False return True def generate_best_choices(level): priority_list = generate_priority_list(level) if level == 1: max_num = 50 unassigned_numbers = list(range(1, 51)) elif level == 2: max_num = 100 unassigned_numbers = list(range(1, 101)) else: max_num = 200 unassigned_numbers = list(range(1, 201)) available_numbers = set(unassigned_numbers) assigned_numbers = set() choices = [] counter = 19 if level == 1 else (37 if level == 2 else 76) while counter > 0 and available_numbers: best_choice = None max_gain = -float('inf') for num in priority_list: if num in available_numbers and can_choose(num, assigned_numbers): opponent_score = calculate_opponent_score(num, assigned_numbers) gain = num - opponent_score if gain > max_gain: max_gain = gain best_choice = num if best_choice is None: break choices.append(best_choice) available_numbers.remove(best_choice) assigned_numbers.add(best_choice) factors = get_factors(best_choice) for factor in factors: if factor != best_choice: assigned_numbers.add(factor) counter -= 1 return choices def generate_all_optimal_solutions(): optimal_solutions = [] for level in range(1, 4): best_choices = generate_best_choices(level) optimal_solutions.append(best_choices) return optimal_solutions optimal_solutions = generate_all_optimal_solutions() p = remote('gz.imxbt.cn', 20275) p.recvuntil(b'3.Quit\n') p.send(b'1\n') for i in range(3): for j in range(len(optimal_solutions[i])): p.recvuntil(b'Choose a Number:') p.send(str(optimal_solutions[i][j]).encode() + b'\n') p.interactive()
运行得到flag
最后flag为
1
flag{Greed, is......key of the life.}
MADer也要当CTFer
题目描述:
1
你知道PRTShark是什么意思吗,P是位置,R是旋转,T是不透明度,S是缩放,而hark代表这道题是hard to hack吧