引子
Advent Of Code是一个年度编程习题活动,每年都会出一些编程题,今年也来试试。可以通过这里 参与。
不给出题目的详细描述啦~
我的代码已经开源到https://github.com/coder109/Advent-Of-Code-2025 。
最后几道题没时间做了,有机会再补吧,有点小难。
1-1:旋转结果为0的次数
我们的任务是这样的,给定一个0-99标号的转盘,初始位置在50,随后通过不断地旋转改变它的位置,求取这个过程在指向0的次数。
这道题的考点就在于对负数取模的操作,这道题的重点是:负数的取模 。在Python中,一个数的模是:
$$
\text{MOD} = N-nK
$$
其中,我们要求的式子是:
$$
\text{MOD} = N % K
$$
所以这道题的思路很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 with open ("1.input" , "r" ) as f: content = f.readlines() initial_position = 50 count = 0 for line in content: if line[0 ] == "R" : initial_position += int (line[1 :]) elif line[0 ] == "L" : initial_position -= int (line[1 :]) initial_position = initial_position % 100 if initial_position == 0 : count += 1 print (count)
也就是说,每次我们只需要旋转,然后对100取模得到实际的位置即可。
1-2:旋转过程中经过0的次数
这道题的思路就要麻烦一些,我们要统计在旋转过程中指向0的次数,比如从50开始,右转550圈,那么就指向了6次0点,我们要统计全部的指向0的次数。那么,我们的思想可以是这样的:
计算当前位置和0之间的距离。
如果旋转的距离大于这个距离,那么就一定指到0了,否则就不用考虑指向0的过程。
那么代码就如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 if __name__ == "__main__" : with open ("1.input" , "r" ) as f: content = f.readlines() position = 50 count = 0 for line in content: position_to_zero_distance = position if line[0 ] == "L" else (100 - position) spin_distance = int (line[1 :]) if spin_distance >= position_to_zero_distance: count += (spin_distance - position_to_zero_distance) // 100 + 1 if line[0 ] == "R" : position += spin_distance elif line[0 ] == "L" : position -= spin_distance position = position % 100 print (count)
我们的思路是这样的,对于与0之间的距离的计算,我们分为两个情况,如果向左旋转,那就是postion本身,如果向右转,就是100-position,随后我们判断经过0的次数,最后更新position即可。
到这里,我们的结果是6239,结果不对,这是为什么?我们忘记考虑0这个边界条件了!当当前的位置为0时,不论向左向右,我们的与0的距离都是100,而不是0。所以我们要对我们的代码做一点更新:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 if __name__ == "__main__" : with open ("1.input" , "r" ) as f: content = f.readlines() position = 50 count = 0 for line in content: position_to_zero_distance = position if line[0 ] == "L" else (100 - position) if position_to_zero_distance == 0 : position_to_zero_distance = 100 spin_distance = int (line[1 :]) if spin_distance >= position_to_zero_distance: count += (spin_distance - position_to_zero_distance) // 100 + 1 if line[0 ] == "R" : position += spin_distance elif line[0 ] == "L" : position -= spin_distance position = position % 100 print (count)
此题通过。
2-1:重复模式的匹配简单版
我们给定了一系列数字的范围,让我们求取这个过程中所有满足条件的数字的和,所谓的条件是这样的,如果一个数字是由两个相同的部分组成的,就算作满足条件,比如11、22、1230612306等。
这道题当然可以用正则匹配、字符串匹配之类的方法做,且更简单,但是这次我们用数论的方法来做。
我们首先能看出来,这样的数字肯定是偶数长度的,否则不可能写作两个相同部分。那么还有什么特点呢,这样的数字实际上满足这样的性质,假设我们的数字有$2N$位,那么这个数字就可以被$10\cdots01$这个数整除,这个数字中0的个数就等于$N-1$,且商为前/后半个$N$位数字。这个证明实在是没有难度,故此略去。
所以,我们的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 with open ("2.input" , "r" ) as f: content = f.readlines() def str_to_valid (num: str ): digit_num = len (num) if digit_num % 2 == 1 : return True division = 10 ** (digit_num / 2 ) + 1 return int (num) % division != 0 for line in content: id_list = line.split("," ) res = 0. for id_elem in id_list: from_id, to_id = id_elem.split("-" ) for i in range (int (from_id), int (to_id) + 1 ): if not str_to_valid(str (i)): res += i print (res)
2-2:重复模式的匹配复杂版
现在我们的目标变了,目的是匹配多次重复的数字,不仅仅是两次,现在123051230512305这种数字也是要匹配到的了。这一次数论的知识貌似不管用了,我们来试一下字符串匹配的机制。我们要做的是一件很简单的事,对于一个长度为$L$的数字,我们要从1位开始切分到$\lfloor\frac{L}{2}\rfloor$位,然后看其它的部分是不是和这一个部分是同样的,如果都是同样的,那么就表明这个数字是来自于某个数字重复得成的,否则,如果有一个部分是不相同的,那么就接着迭代。如果没有一次迭代成功,那么就不需要被匹配到,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 with open ("2.input" , "r" ) as f: content = f.readlines() def str_to_valid (num: str ): if len (num) == 1 : return True for cut_elem_len in range (1 , len (num) // 2 + 1 ): pattern = num[:cut_elem_len] is_good = False for target_idx in range (cut_elem_len, len (num), cut_elem_len): if num[target_idx:target_idx + cut_elem_len] != pattern: is_good = True if not is_good: return False return True for line in content: id_list = line.split("," ) res = 0. for id_elem in id_list: from_id, to_id = id_elem.split("-" ) for i in range (int (from_id), int (to_id) + 1 ): if not str_to_valid(str (i)): res += i print (res)
3-1:寻找最大数字的二位子串
我们被给定了一些全是数字的字符串,我们要寻找这里面最大的数字,比如987654321,就是98,897654321,就是97,对于一个数字,其左边的数字在给定字符串中,必须要出现在右边数字的左边。这道题很直觉的是,十位数大,那就是真的大。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 with open ("3.input" , "r" ) as f: content = f.readlines() def find_max_in_line (line: str ): max_val, max_idx = -1 , -1 for i in range (len (line)): if int (line[i]) > max_val: max_val = int (line[i]) max_idx = i return max_val, max_idx result = 0 for line in content: line = line.strip() first_large, first_idx = find_max_in_line(line) if first_idx == len (line) - 1 : second_large, second_idx = find_max_in_line(line[:first_idx]) result += second_large * 10 + first_large else : second_large, second_idx = find_max_in_line(line[first_idx+1 :]) result += first_large * 10 + second_large print (result)
其思想是,首先寻找最大的数字,如果这个数字出现在末尾,就表明它只能当作个位的数字,否则就可以当作十位的数字。
3-2:寻找最大数字的十二位子串
这道题的思路和上一道题有一定的差别,对于这个12位数,我们不能按照第一题的思想来了,而是需要这样思考:12位数的第一位,可以在序列的第一位到从最后开始数起的第11位里取,因为第一位大,那么整个数字就大,不必考虑后续。所以代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 with open ("3.input" , "r" ) as f: content = f.readlines() def find_max_in_line (line: str ): max_val, max_idx = -1 , -1 for i in range (len (line)): if int (line[i]) > max_val: max_val = int (line[i]) max_idx = i return max_val, max_idx result = 0 for line in content: line = line.strip() temp_result = 0 first_idx = 0 for idx in range (12 ): first_large, tmp_first_idx = find_max_in_line(line[first_idx:-11 + idx if idx-11 != 0 else None ]) if first_large == -1 : first_large = int (line[first_idx]) tmp_first_idx = 0 first_idx = first_idx + tmp_first_idx + 1 temp_result = temp_result * 10 + first_large result += temp_result print (result)
这里有一点是,对于Python来说,[:-1]是不包括最后一位的,而[:0]是无意义的,所以说要在这里做一个判断,如果find_max_in_line()返回了-1,就表明输入序列为0长度,idx-11和first_idx是重合的,需要注意。
4-1:寻找邻近格子元素少于4的元素个数
这道题给定了一个图,每个格子有一个“纸卷”,我们要找到周围邻近八个格子纸卷数少于4个的纸卷个数,那么这道题就直接判断即可,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 with open ("4.input" , "r" ) as f: content = f.readlines() height, width = len (content), len (content[0 ].strip()) graph = [[0 for _ in range (width+2 )] for _ in range (height+2 )] result = 0 for h_idx in range (1 , height+1 ): for w_idx in range (1 , width+1 ): curr_item = content[h_idx-1 ][w_idx-1 ] if curr_item == "@" : graph[h_idx][w_idx] = 1 for h_idx in range (1 , height+1 ): for w_idx in range (1 , width+1 ): if graph[h_idx][w_idx] == 0 : continue adjacent_num = 0 if graph[h_idx-1 ][w_idx] == 1 : adjacent_num += 1 if graph[h_idx+1 ][w_idx] == 1 : adjacent_num += 1 if graph[h_idx][w_idx-1 ] == 1 : adjacent_num += 1 if graph[h_idx][w_idx+1 ] == 1 : adjacent_num += 1 if graph[h_idx+1 ][w_idx+1 ] == 1 : adjacent_num += 1 if graph[h_idx+1 ][w_idx-1 ] == 1 : adjacent_num += 1 if graph[h_idx-1 ][w_idx+1 ] == 1 : adjacent_num += 1 if graph[h_idx-1 ][w_idx-1 ] == 1 : adjacent_num += 1 if adjacent_num < 4 : result += 1 print (result)
最后的一大堆if是AI生成,省时省力。
4-2:全部能挪走的元素
在挪走可以挪走的元素(邻近小于4的元素)之后,我们可以挪走更多的元素,那么最后能挪走多少?这便是题干要求,模拟即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 with open ("4.input" , "r" ) as f: content = f.readlines() height, width = len (content), len (content[0 ].strip()) graph = [[0 for _ in range (width+2 )] for _ in range (height+2 )] total_result = 0 result = 0 for h_idx in range (1 , height+1 ): for w_idx in range (1 , width+1 ): curr_item = content[h_idx-1 ][w_idx-1 ] if curr_item == "@" : graph[h_idx][w_idx] = 1 while True : result = 0 mem_list = [] for h_idx in range (1 , height+1 ): for w_idx in range (1 , width+1 ): if graph[h_idx][w_idx] == 0 : continue adjacent_num = 0 if graph[h_idx-1 ][w_idx] == 1 : adjacent_num += 1 if graph[h_idx+1 ][w_idx] == 1 : adjacent_num += 1 if graph[h_idx][w_idx-1 ] == 1 : adjacent_num += 1 if graph[h_idx][w_idx+1 ] == 1 : adjacent_num += 1 if graph[h_idx+1 ][w_idx+1 ] == 1 : adjacent_num += 1 if graph[h_idx+1 ][w_idx-1 ] == 1 : adjacent_num += 1 if graph[h_idx-1 ][w_idx+1 ] == 1 : adjacent_num += 1 if graph[h_idx-1 ][w_idx-1 ] == 1 : adjacent_num += 1 if adjacent_num < 4 : result += 1 mem_list.append([h_idx, w_idx]) if result == 0 : break for mem in mem_list: graph[mem[0 ]][mem[1 ]] = 0 total_result += result print (total_result)
5-1:区间判断
我们被给定了一些区间和一些数字,我们要判断数字是否在所有区间的并集中。第一个问可以直接去除重复的区间,然后进行判断:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 with open ("5.input" , "r" ) as f: content = f.readlines() range_list, num_list = [], [] num_mode = False for line in content: if len (line.strip()) == 0 : num_mode = True continue if num_mode: num_list.append(int (line.strip())) else : range_start, range_end = [int (x) for x in line.strip().split("-" )] range_list.append([range_start, range_end]) range_list = sorted (range_list, key=lambda x: x[0 ]) sanitized_range_list = [range_list[0 ]] for range_idx in range (1 , len (range_list)): curr_elem = range_list[range_idx] curr_start, last_end = curr_elem[0 ], sanitized_range_list[-1 ][1 ] if curr_start > last_end: sanitized_range_list.append(curr_elem) elif curr_start == last_end: sanitized_range_list[-1 ][1 ] = curr_elem[1 ] else : sanitized_range_list[-1 ][1 ] = max (curr_elem[1 ], last_end) num_list = sorted (num_list) valid_count = 0 for num in num_list: for range_elem in sanitized_range_list: if range_elem[0 ] <= num <= range_elem[1 ]: valid_count += 1 break print (valid_count)
实际上,第三个循环可以进行优化。
5-2:区间并集的数字个数
第二题实际上很简单,就是计算我们在第一题中求出的共同区间的所有数字个数,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 with open ("5.input" , "r" ) as f: content = f.readlines() range_list, num_list = [], [] for line in content: if len (line.strip()) == 0 : break range_start, range_end = [int (x) for x in line.strip().split("-" )] range_list.append([range_start, range_end]) range_list = sorted (range_list, key=lambda x: x[0 ]) sanitized_range_list = [range_list[0 ]] for range_idx in range (1 , len (range_list)): curr_elem = range_list[range_idx] curr_start, last_end = curr_elem[0 ], sanitized_range_list[-1 ][1 ] if curr_start > last_end: sanitized_range_list.append(curr_elem) elif curr_start == last_end: sanitized_range_list[-1 ][1 ] = curr_elem[1 ] else : sanitized_range_list[-1 ][1 ] = max (curr_elem[1 ], last_end) valid_count = 0 for range_elem in sanitized_range_list: valid_count += range_elem[1 ] - range_elem[0 ] + 1 print (valid_count)
6-1:所有运算的加和
这道题就是求每一列的运算结果的和。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 with open ("6.input" , "r" ) as f: content = f.readlines() operate_list, num_list_list = [], [] for line in content: line_elem = line.strip().split(" " ) remove_list = [] for idx in range (len (line_elem)): if len (line_elem[idx].strip()) == 0 : remove_list.append(idx) for idx in sorted (remove_list, reverse=True ): del line_elem[idx] if "*" in line_elem: operate_list = line_elem else : num_list_list.append(line_elem) result = 0 for idx, operation in enumerate (operate_list): temp_result = 0 if operation == "*" : temp_result = 1 for num_list in num_list_list: temp_result *= int (num_list[idx]) elif operation == "+" : for num_list in num_list_list: temp_result += int (num_list[idx]) else : print (operation) raise NotImplementedError result += temp_result print (result)
6-2:数字变成竖着写的啦!
这道题的每个列的数字变成竖着写的了,要求我们取每一列的数字组成一个新的数字进行运算。这道题的关键在于,每个数字如今要竖着看的话,就表明我们首先需要将它们对齐,然后竖着取数字。那么首先,我们容易想到这样一个规律,就是在每一行中都按顺序遍历,如果过一个位,每行都是空格,就表明我们读取完毕了一个数字。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 with open ("6.input" , "r" ) as f: content = f.readlines() for content_idx in range (len (content)): content[content_idx] = content[content_idx][:-1 ] def add_num_buffer (num_buffer: list [str ], op: str ) -> int : result = 0 if op == '+' else 1 idx = 0 while idx < len (num_buffer[0 ]): curr_result = "" for line in num_buffer: curr_result += "" if line[idx] == "" else line[idx] result = result + int (curr_result) if op == '+' else result * int (curr_result) idx += 1 return result num_lines = content[:-1 ] max_line_len = max ([len (line) for line in num_lines]) raw_op_line = content[-1 ].strip() op_line = [] for op_char in raw_op_line: if op_char == '+' : op_line.append('+' ) elif op_char == '*' : op_line.append('*' ) idx, op_idx = 0 , 0 num_buffer = ["" for _ in range (len (num_lines))] result = 0 while idx < max_line_len : is_all_space = True for line in num_lines: if line[idx] != ' ' : is_all_space = False break if is_all_space: result += add_num_buffer(num_buffer, op_line[op_idx]) num_buffer = ["" for _ in range (len (num_lines))] op_idx += 1 else : for line_idx, line in enumerate (num_lines): num_buffer[line_idx] += line[idx] idx += 1 result += add_num_buffer(num_buffer, op_line[op_idx]) num_buffer = ["" for _ in range (len (num_lines))] print (result)
这道题比较tricky一些,思路是这样的:
将数字行和运算符行分开,这里,不能用strip,否则会将一些行最后的空格也删掉。
用一个idx遍历每一个位置,如果它们全都是空格,就将num_buffer中的数字进行运算。
否则,就在num_buffer中加入读取到的字符。
7-1:向下行进的分歧次数
给了一张图,从上往下走,遇到一个^就分裂成左右两条路,计算分裂的次数。就是个模拟题。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 with open ("7.input" , "r" ) as f: content = f.readlines() graph = [] for line in content: graph.append([]) for c in line.strip(): graph[-1 ].append(c if c != "S" else "1" ) result = 0 for line_idx in range (len (graph[1 :])): for char_idx in range (len (graph[line_idx])): if graph[line_idx-1 ][char_idx] == "1" and graph[line_idx][char_idx] == "^" : result += 1 if char_idx == 0 : graph[line_idx][char_idx+1 ] = "1" elif char_idx == len (graph[line_idx]) - 1 : graph[line_idx][char_idx-1 ] = "1" else : graph[line_idx][char_idx-1 ] = "1" graph[line_idx][char_idx+1 ] = "1" elif graph[line_idx-1 ][char_idx] == "1" : graph[line_idx][char_idx] = "1" print (result)
7-2:向下行进的不同路径
现在,分裂的方向是不确定的,让我们算所有可能的路径。这个时候只需要在每次分裂的时候,记录到这个分裂点共有几条路即可。代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 with open ("7.input" , "r" ) as f: content = f.readlines() graph = [] for line in content: graph.append([]) for c in line.strip(): if c == "S" : graph[-1 ].append([1 ]) elif c == "." : graph[-1 ].append([0 ]) elif c == "^" : graph[-1 ].append([-1 ]) else : raise NotImplementedError barrier = -1 for line_idx in range (1 , len (graph[1 :])+1 ): for elem_idx in range (len (graph[line_idx])): upper_flow = graph[line_idx-1 ][elem_idx][0 ] curr_terrain = graph[line_idx][elem_idx][0 ] if curr_terrain == barrier: if elem_idx == 0 : graph[line_idx][elem_idx+1 ][0 ] += upper_flow elif elem_idx == len (graph[line_idx]) - 1 : graph[line_idx][elem_idx-1 ][0 ] += upper_flow else : graph[line_idx][elem_idx-1 ][0 ] += upper_flow graph[line_idx][elem_idx+1 ][0 ] += upper_flow elif curr_terrain != barrier and upper_flow != barrier: graph[line_idx][elem_idx][0 ] += upper_flow result = 0 for lst in graph[-1 ]: curr_result = lst[0 ] result += curr_result if curr_result > barrier else 0 print (result)
8-1:最大三个子图的节点数之积
给定了一些三维坐标,每次连接距离最小的两个节点,最后求三个最大子图的节点数之积。图论是我最弱的一项算法领域了。说实话这道题我没什么好的想法,只有暴力+BFS。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 import mathdef calc_dist (x1, y1, z1, x2, y2, z2 ): return math.sqrt(math.pow (x1 - x2, 2 ) + math.pow (y1 - y2, 2 ) + math.pow (z1 - z2, 2 )) def bfs (graph: list [list [int ]], start: int , visited: list [bool ], visit_stack: list [int ] ) -> int : max_hop = 1 node_queue = [start] while len (node_queue) > 0 : curr_node = node_queue.pop(0 ) for neighbor in graph[curr_node]: if visited[neighbor]: continue visited[neighbor] = True visit_stack.append(neighbor) node_queue.append(neighbor) max_hop = max (max_hop, len (visit_stack)) return max_hop distance_list = [] connect_limit = 1000 with open ("8.input" , "r" ) as f: content = f.readlines() coordinate_list = [] for line in content: coordinate_list.append([int (x) for x in line.strip().split("," )]) for i in range (len (coordinate_list)): for j in range (i + 1 , len (coordinate_list)): distance = calc_dist(coordinate_list[i][0 ], coordinate_list[i][1 ], coordinate_list[i][2 ], coordinate_list[j][0 ], coordinate_list[j][1 ], coordinate_list[j][2 ]) distance_list.append([[i, j], distance]) distance_list.sort(key=lambda x: x[1 ]) graph = [[] for i in range (len (coordinate_list))] for i in range (connect_limit): connect_from, connect_to = distance_list[i][0 ] graph[connect_from].append(connect_to) graph[connect_to].append(connect_from) visited = [False for i in range (len (coordinate_list))] hop_list = [] for i in range (len (coordinate_list)): if visited[i]: continue visited[i] = True visit_stack = [i] max_hop, curr_hop = 1 , 1 hop_list.append(bfs(graph, i, visited, visit_stack) if graph[i] != [] else 1 ) hop_list.sort() print (hop_list)result = 1 result = result * hop_list[-1 ] * hop_list[-2 ] * hop_list[-3 ] print (result)
8-2:何时为连通图
这道题依旧是按照上一道题的连接方法,只不过这次,让我们计算连接成一张图时候,最后连接的两个x坐标之积。连通图最少有n-1条边,非连通图的边少于n-1条,故代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import mathwith open ("8.input" , "r" ) as f: content = f.readlines() def calc_dist (x1, y1, z1, x2, y2, z2 ): return math.sqrt(math.pow (x1 - x2, 2 ) + math.pow (y1 - y2, 2 ) + math.pow (z1 - z2, 2 )) def get_visit_node_num (l ): result = 0 for i in l: if not node_visited[i]: result += 1 return result coordinate_list = [] distance_list = [] for line in content: coordinate_list.append([int (x) for x in line.strip().split("," )]) for i in range (len (coordinate_list)): for j in range (i + 1 , len (coordinate_list)): distance = calc_dist(coordinate_list[i][0 ], coordinate_list[i][1 ], coordinate_list[i][2 ], coordinate_list[j][0 ], coordinate_list[j][1 ], coordinate_list[j][2 ]) distance_list.append([[i, j], distance]) distance_list.sort(key=lambda x: x[1 ]) node_visited = [False for i in range (len (coordinate_list))] node_num, connect_num = 0 , 0 for distance_elem in distance_list: connect_from, connect_to = distance_elem[0 ] if not node_visited[connect_from] and not node_visited[connect_to]: node_visited[connect_from] = True node_visited[connect_to] = True node_num += 2 connect_num += 1 elif not node_visited[connect_from] and node_visited[connect_to]: node_visited[connect_from] = True node_num += 1 connect_num += 1 elif node_visited[connect_from] and not node_visited[connect_to]: node_visited[connect_to] = True node_num += 1 connect_num += 1 else : connect_num += 1 if connect_num >= len (coordinate_list) - 1 and node_num == len (coordinate_list): print (coordinate_list[connect_from][0 ] * coordinate_list[connect_to][0 ]) break
9-1:最大的方块
给定一些二维坐标,求这些坐标点之间能形成的最大方块的面积,暴力:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 with open ("9.input" , "r" ) as f: content = f.readlines() def calc_area (x1, y1, x2, y2 ): return (x2 - x1 + 1 ) * (y2 - y1 + 1 ) coordinate_list = [] for line in content: coordinate_list.append([int (x) for x in line.strip().split("," )]) max_area = 0 for i in range (len (coordinate_list)): for j in range (i + 1 , len (coordinate_list)): x1, y1 = coordinate_list[i][0 ], coordinate_list[i][1 ] x2, y2 = coordinate_list[j][0 ], coordinate_list[j][1 ] max_area = max (max_area, calc_area(min (x1, x2), min (y1, y2), max (x1, x2), max (y1, y2))) print (max_area)