一道朋友圈的题

本文探讨了一笔画问题,即将图中的所有空心圆通过不重复的路径连接起来的挑战。通过对问题进行转化,将其视为寻找哈密顿路径的过程,并使用递归搜索算法进行了尝试。虽然未找到可行解,但提供了有趣的问题背景和解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

一个题目,先上题目。
这里写图片描述
我的理解:用一笔连接图中的所有空心圆,不能出现斜线。只能在空心圆处90度拐弯,只能经过一个顶点一次。

问题转化

感觉到应该是一个图上的问题。所有的空心圆都是顶点,两个顶点之间有边当且仅当这两个顶点所对应的空心圆是相邻的,记这个图为G(V,E)。问题变为找到图上的一条路pp经过图上所有的顶点,并且每个顶点只经过一次。

变成了一个搜索问题。即以任意途中顶点v开始,寻找满足约束的路。所以,索性这样改造一下图。在V中加入顶点v代表实心圆。原来的任意顶点u都与顶点v在新图G上有边,即(u,v)E。这样就形成了新图G(u,v)。这样直接从v顶点开始在树上搜索就可以了。

python代码如下。

import time
graph = [
       [0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,],
       [0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [1,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,],
       [0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,],
       [0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,],
       ]

def find_next(prefix_path, graph):
    if len(prefix_path) == 25 :
        print("path: %s"%prefix_path)
    cur_node = prefix_path[-1]
    next_queue = []
    for i in range(25):
        if graph[cur_node][i] == 1 and i not in prefix_path:
                next_queue.append(i)
    for next_node in next_queue:
        next_prefix_path = prefix_path + [next_node]
        find_next(next_prefix_path, graph)
counter = 0
start_time = time.time()
find_next([1], graph)

运行的结果是没有打印。所以这个问题应该没有可行解。

一点思考

可以发现。如果原问题的每个解,等价于在G(V,E)上的一个哈密顿环。设G上一个哈密顿环为h,那么只需要将顶点v去掉就可以得到一个原问题的解。反之亦然。所以问题就变成了寻找图G上的哈密顿环。当然可以先判断G上是否存在哈密顿环。(没找到这个存在性问题的较低复杂性的算法。)

原问题的解

这个问题原来是有人发在朋友圈的,所以我问他有答案吗。他说有的(吃了一鲸)。答案是这样的(说是脑筋急转弯):
这里写图片描述
仁者见仁,智者见智。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值