Python3 欧拉计划 问题81-85

EulerProject.png

问题76-80参见:https://www.jianshu.com/p/8d4d53f7d18e

81、最小路径和(初级)  2个方向

  在如下5*5的数字矩阵中,只能向右或向下移动,从左上角到右下角的最小路径和为2427=131+201+96+342+746+422+121+37+331,路径已由红色数字标出:

matrix.png

在文件matrix.txt中包含了一个80*80的矩阵,求该矩阵的左上角到右下角的最小路径和。

Python3解答 动态回归思想参见
import numpy as np
fan=open(r'C:\Users\GWT9\Desktop\p081_matrix.txt')
an =[]
#读取数据
while 1:
    x=fan.readline()
    if len(x) == 0:
        break
    du = []
    for jjj in list(x.split(',')):
        du.append(jjj)
    an.append(du)
fan.close()

npan = np.array(an, dtype=int)#转化为np数组形式
#从左上角开始生成斜线坐标直到右下角
weizhi = []
for jj in range(2 * len(npan) - 2):
    sonweizhi = []
    if jj < len(npan):
        for dd in range(jj + 1):
            sonweizhi.append([dd, jj - dd])
    else:
        for dd in range(jj - len(npan) + 1, len(npan)):
            sonweizhi.append([dd, jj - dd])
    weizhi.append(sonweizhi)
weizhi.append([[len(npan) -1, len(npan) - 1]])

#开始逐斜线计算直到右下角【动态规划思想】
for jj in weizhi[1:]:
    for ii in jj:
        if ii[0] == 0:
            npan[ii[0], ii[1]] += npan[ii[0], ii[1] - 1]
        elif ii[1] == 0:
            npan[ii[0], ii[1]] += npan[ii[0] -1, ii[1]]
        else:
            npan[ii[0], ii[1]] += min(npan[ii[0] -1, ii[1]], npan[ii[0], ii[1] - 1])
#输出最终的结果
print(npan[len(npan) -1, len(npan) - 1])
答案:427337

82、最小路径和(中级)  3个方向

  在如下5*5的数字矩阵中,从最左列任意一格出发,只能向右、向上或向下移动,到最右列任意一格结束的最小路径和为994=201+96+342+234+103+18,路径已由红色数字标出:

matrix.png

在文件matrix.txt中包含了一个80*80的矩阵,求该矩阵的最左列到最右列的最小路径和。

Python3解答 动态回归思想参见
import numpy as np
fan=open(r'C:\Users\GWT9\Desktop\p082_matrix.txt')
an =[]
#读取数据
while 1:
    x=fan.readline()
    if len(x) == 0:
        break
    du = []
    for jjj in list(x.split(',')):
        du.append(jjj)
    an.append(du)
fan.close()
npan = np.array(an, dtype=int).T#转化为np数组形式转置
copynpan = npan.copy()
#定义组合函数
def combine(nplist, mcode):
    comlist = []
    for i in range(len(nplist)):
        dnum = 0
        if i < mcode:
            cc = i + 1
            while cc < mcode:
                dnum += nplist[cc]
                cc += 1
            comlist.append(dnum)
        elif i == mcode:
            pass
        else:
            cc = i - 1
            while cc > mcode:
                dnum += nplist[cc]
                cc -= 1
            comlist.append(dnum)
    return comlist

for jj in range(1, len(npan)):#开始逐行进行计算【动态规划】
    for gg in range(len(npan[jj])):#直接运算
        npan[jj, gg] += npan[jj-1, gg]
    if jj < len(npan) - 1:
        Dcopynpan = copynpan.copy()
        for ii in range(len(npan[jj])):#开始比较运算
            if ii == 0:
                copynpan[jj, ii] += min(copynpan[jj - 1, ii], np.min(npan[jj][1 :] + np.array(combine(Dcopynpan[jj], ii))))#需要比较所有路径
            elif ii == len(npan[jj]) - 1:
                copynpan[jj, ii] += min(copynpan[jj - 1, ii], np.min(npan[jj][: -1] + np.array(combine(Dcopynpan[jj], ii))))#需要比较所有路径
            else:
                addlist = np.array(list(npan[jj][: ii]) + list(npan[jj][ii + 1 :]))
                copynpan[jj, ii] += min(copynpan[jj - 1, ii], np.min(np.array(combine(Dcopynpan[jj], ii)) + addlist))#需要比较所有路径
        npan = copynpan.copy()
    else:
        print(np.min(npan[-1]))
答案:260324

83、最小路径和(高级)  4个方向

  在如下5*5的数字矩阵中,从左上角到右下角任意地向上、向下、向左或向右移动的最小路径和为2297=131+201+96+342+234+103+18+150+111+422+121+37+331,路径已由红色数字标出:

matrix.png

在文件matrix.txt中包含了一个80*80的矩阵,求该矩阵的左上角到右下角的最小路径和。

Python3解答 Dijkstra 算法
import numpy as np
fan=open(r'C:\Users\GWT9\Desktop\p083_matrix.txt')
an =[]
#读取数据
while 1:
    x=fan.readline()
    if len(x) == 0:
        break
    du = []
    for jjj in list(x.split(',')):
        du.append(jjj)
    an.append(du)
fan.close()
npan = np.array(an, dtype=int)#转化为np数组形式转置
copynpan = np.array(npan.copy(), dtype = float)
#开始
zuibiaoset = []
for jj in range(len(npan)):
    for gg in range(len(npan)):
        copynpan[jj, gg] = float('inf')
copynpan[0, 0] = npan[0, 0]
#构建联通字典
liantong = {}
for gg in range(len(npan)):
    for hh in range(len(npan)):
        dd = [[gg - 1, hh],[gg + 1, hh],[gg, hh - 1],[gg, hh + 1]]
        liantong[(gg, hh)] = []
        for ff in dd:
            if ff[0] >=0 and ff[0] < len(npan) and ff[1] >=0 and ff[1] < len(npan):
                liantong[(gg, hh)].append(ff)
#Dijkstra 算法
def Dijkstra(startlist, lidict = liantong, yuanshi = npan, com = copynpan):
    start = []
    if startlist == []:
        return com
    else:
        for gg in startlist:
            fulist = lidict[(gg[0], gg[1])]
            for jjj in fulist:
                comnumber = com[gg[0], gg[1]] + yuanshi[jjj[0], jjj[1]]
                if comnumber < com[jjj[0], jjj[1]]:
                    com[jjj[0], jjj[1]] = comnumber
                    start.append(jjj)
    return Dijkstra(start)
print(int(Dijkstra([[0, 0]])[-1,-1]))
答案:425185

84、大富翁

答案参见: https://www.jianshu.com/p/758674dfe2cb

85、长方形个数

  正如下图所示,在一个3*2的长方形网格中含有18=6+4+2+3+2+1个不同大小的长方形:

  虽然不存在恰好含有200万个长方形的长方形网格,但有许多长方形网格中含有的长方形数接近200万,求其中最接近这一数的长方形网格的面积。

Python3解答
import numpy as np
i = 1
sanp = np.zeros((3000, 3000))#存储个数
start = 1
num = 100000
sign = 0
while 1:
    for j in range(1, start + 1):
        sanp[i, j] = sanp[j, i] = sanp[i - 1, j] + sanp[i, j - 1] - sanp[i - 1, j - 1] + i * j#动态规划方法
        #计算最小的差值
        result = abs(2e6 - sanp[i, j])
        if num > result:
            num = result
            re =[i, j].copy()
        if j == 1 and sanp[i, j] > 2e6:
            sign = -1
            break
        if sanp[i, j] > 2e6:
            sign = 1
            start = j
    if sign != 1:
        start += 1
    if sign == -1:
        break
    i += 1
print(re[0] * re[1])
答案:2772

持续更新,欢迎讨论,敬请关注!!!  

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,635评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,543评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,083评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,640评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,640评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,262评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,833评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,736评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,280评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,369评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,503评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,870评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,340评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,460评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,909评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,512评论 2 359