算法趣题-Q25

一、问题描述

二、问题分析

        此类具体的题目最常见的做法就是模拟求解,在模拟求解的过程中,需要遍历所有可能的情况,然后需要注意的就是如何计算交叉点,这在本书中有提到,也正如Python代码实现,此处不多介绍。

        而另一种方法如C/C++实现将具体的问题进行进一步的抽象和转化,将问题简化为若干根直线具有的最多交点数目,再减去鞋带孔自带的交点就是目标所求(读者可以进行简单地验证)。

三、代码实现

1.C/C++实现

#include <iostream>
#include <vector>

using namespace std;

vector<int> 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;
}

2.Python实现

# 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值