前几天遇到这样一道数学题:
用四种不同颜色给三棱柱六个顶点涂色,要求每个点涂一种颜色,且每条棱的两个端点涂不同颜色,则不同的涂色方法有多少种?
当我看完题目后,顿时不知所措。于是我拿起草稿纸在一旁漫无目的地演算了一下,企图能找到解决方法。结果一无所获。于是打算通过程序算法解决这个问题。经过2个多小时的研究,终于完成了代码,并求得了答案。
由于Python写起来比较方便而且本人比较喜欢Python的语法,所以研究算法时我通常采用Python,此次也不例外。以下就是整个算法的实现过程。
两种算法
我一共想出了两种用于解决本题的算法:
算法一:将所有的涂色情况通过程序的循环计算出来,然后通过程序的条件判断去除掉不合题意的所有情况,最后得到最终结果。
算法二:从其中任意一个端点(p0)入手,由于其它所有端点都没有涂色,所以它可以涂四种颜色。将这四种颜色通过循环分别涂在这个端点上,每涂上一种颜色后,获取与它相临的一个端点(p1),并获取它可以涂上的颜色,然后通过循环将可用颜色涂上(及不能涂上与p0相同的颜色),每涂上一种颜色,又将p1相邻的未涂色的点涂色(及除p0外其他的相邻端点)。每个点被涂色后都采用同样的方法将相邻的点涂色,以此类推,涂完最后一个点,就记一次情况。所有的递归都完成后,就获得了所有情况。
算法一很直接很粗暴,所以我采用了算法二来解决上述问题。接下来就是具体的代码了。
算法实现
我写了大约90行Python代码来实现这个算法:
colorList = [0, 1, 2, 3]
pointList = []
amount = 0
class Point(object):
def __init__(self):
super(Point, self).__init__()
self.neibors = []
self.color = None
def paint(self, c):
self.color = c
def clean(self):
self.color = None
def getLeftOverColors(self):
copyOfColorList = colorList[0 : 4]
for neibor in self.neibors:
nc = neibor.color
if nc in copyOfColorList:
copyOfColorList.remove(nc)
return copyOfColorList
def main():
global pointList
p0 = Point()
p1 = Point()
p2 = Point()
p3 = Point()
p4 = Point()
p5 = Point()
p0.neibors = [p1, p2, p4]
p1.neibors = [p0, p2, p5]
p2.neibors = [p0, p1, p3]
p3.neibors = [p2, p4, p5]
p4.neibors = [p0, p3, p5]
p5.neibors = [p4, p3, p1]
pointList = [p0, p1, p2, p3, p4, p5]
paintPoint(p0)
print(amount)
def paintPoint(p):
global amount
colors = p.getLeftOverColors()
lastOne = isLastOne()
for c in colors:
p.paint(c)
if lastOne:
amount += 1
else:
for currentNeibor in p.neibors:
if currentNeibor.color == None:
paintPoint(currentNeibor)
break
p.clean()
def isLastOne():
global pointList
paintedNum = 0
for p in pointList:
if p.color != None:
paintedNum += 1
return paintedNum == 5
if __name__ == "__main__":
main()
以下是对各段代码的介绍。
全局变量
colorList:颜色列表
pointList:存放六个点的列表
amount : 涂色方案的种数
Point类
用于储存各个点的信息,如点的颜色(color属性,None代表无颜色)、相邻的点('neibors'属性)。以及提供paint方法用于将点标记颜色;clean方法用于去除颜色;getLeftOverColors方法用于获取可用颜色,及获取相邻点没有使用的颜色。
main函数
程序开始运行时调用的函数,其中构造了所需的六个点,以及分别为这六个点明确了相邻的三个点。注意,由于这里的点只有相邻和不相邻的位置关系,所以不需要在意这些点到底在三棱柱里对应哪个位置,任意设定这些点的位置对结果来说并没有影响,只需注意它们之间的相邻关系即可。
isLastOne函数
判断是不是最后一个未涂色的点。
paintPoint函数
用于对作为参数传入的点进行着色。其中首先通过调用该点的getLeftOverColors方法获取可用颜色,然后按照上文算法中介绍的,通过遍历可用颜色列表,为该点着色,如果该点不是最后一个点(通过isLastOne函数判断),就递归调用paintPoint函数为相邻的一个未着色的点着色,如果是,则将记下一次涂色方案。
运行代码,得到结果 - 264:
Ok,于是这道题就在我们的计算机的帮助下,被成功解决掉了~如果大家有更好的方案解决这一算法问题,欢迎留言进行交流~希望本文对大家学习Python和计数原理都能有所帮助。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]

