此类具体的题目最常见的做法就是模拟求解,在模拟求解的过程中,需要遍历所有可能的情况,然后需要注意的就是如何计算交叉点,这在本书中有提到,也正如Python代码实现,此处不多介绍。
而另一种方法如C/C++实现将具体的问题进行进一步的抽象和转化,将问题简化为若干根直线具有的最多交点数目,再减去鞋带孔自带的交点就是目标所求(读者可以进行简单地验证)。
三、代码实现 1.C/C++实现#include2.Python实现#include using namespace std; vector joints; int get_result(int); int get_joints(int); int get_result(int n) { // 获取 n 对孔时,中间能有的最大交点数 int lines = 2 * n - 1; // 需要连接的线段数 int fixed = 2 * (n - 1); // 已经自带的交点数 = 孔数 - 2 return get_joints(lines) - fixed; } int get_joints(int n) { // n 条直线能有的最大交点数目 if (n <= 0) { joints.clear(); joints.push_back(0); return 0; } while (joints.size() <= size_t(n)) joints.push_back(get_joints(n - 1) + n - 1); return joints[n]; } int main() { cout << get_result(6) << endl; return 0; }
# coding=utf-8
from itertools import permutations
def count_joint(path):
joints = 0
_len = len(path)
for i in range(_len):
for j in range(i + 1, _len):
if (path[i][0] - path[j][0]) * (path[i][1] - path[j][1]) < 0:
joints += 1
print(path, joints)
return joints
def get_result(n):
perm = tuple(permutations(range(1, n)))
p_len = len(perm)
result = 0
for i in range(p_len): # 左侧排列
for j in range(p_len): # 右侧排列
path = []
left = 0
right = perm[j][0]
for k in range(n - 1):
path.append((left, right))
left = perm[i][k]
path.append((left, right))
if k < n - 2:
right = perm[j][k + 1]
path.append((left, 0))
result = max(count_joint(path), result)
return result
if __name__ == '__main__':
print(get_result(6))
pass



