求一个矩阵中连续四个数字(行,列,正、反对角线)乘积的最大值。

最近在project Euler题目上,见到一个题觉得不错,就花时间做了一下。
问题:
a=[
[8, 2, 22,97,38,15,0,40,0,75, 4, 5, 7,78, 52, 12, 50, 77, 91, 8],
[49 ,49 ,99 ,40 ,17 ,81 ,18 ,57 ,60 ,87 ,17 ,40 ,98 ,43 ,69 ,48 ,4 ,56 ,62,0],
[81 ,49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65],
[52 ,70 ,95, 23 ,4 ,60 ,11 ,42 ,69 ,24 ,68 ,56 ,1 ,32 ,56 ,71 ,37,2 ,36 ,91],
[22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80],
[24 ,47 ,32 ,60 ,99 ,3 ,45 ,2 ,44 ,75 ,33 ,53 ,78 ,36 ,84 ,20 ,35 ,17 ,12 ,50],
[32 ,98 ,81 ,28 ,64 ,23 ,67 ,10 ,26 ,38 ,40 ,67 ,59 ,54 ,70 ,66 ,18 ,38 ,64 ,70],
[67 ,26 ,20 ,68 ,2 ,62 ,12 ,20 ,95 ,63 ,94 ,39 ,63 ,8 ,40 ,91 ,66 ,49 ,94 ,21],
[24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72],
[21 ,36 ,23 ,9 ,75, 0,76 ,44 ,20 ,45 ,35 ,14, 0,61 ,33 ,97, 34 ,31, 33 ,95],
[78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92],
[16 ,39 ,5 ,42 ,96 ,35 ,31 ,47 ,55 ,58 ,88 ,24 ,0 ,17 ,54 ,24 ,36 ,29 ,85 ,57],
[86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58],
[19 ,80 ,81 ,68 ,5 ,94 ,47 ,69 ,28 ,73 ,92 ,13 ,86 ,52 ,17 ,77 ,4 ,89 ,55 ,40],
[4 ,52 ,8 ,83 ,97 ,35 ,99 ,16 ,7 ,97 ,57 ,32 ,16 ,26 ,26 ,79 ,33 ,27 ,98 ,66],
[88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69],
[4 ,42 ,16 ,73 ,38 ,25 ,39 ,11 ,24 ,94 ,72 ,18 ,8 ,46 ,29 ,32 ,40 ,62 ,76 ,36],
[20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16],
[20 ,73 ,35 ,29 ,78 ,31 ,90 ,1 ,74 ,31 ,49 ,71 ,48 ,86 ,81 ,16 ,23 ,57 ,5 ,54],
[1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48]]
In the 20×20 grid below, four numbers along a diagonal line have been marked in red.

The product of these numbers is 26 × 63 × 78 × 14 = 1788696.

What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?
首先打算写一个关于矩阵转置的函数:

# 例:将矩阵转置
def arry_reverse(list1):
    list2=[]
    m=len(list1)    # 原矩阵行数
    n=len(list1[0]) # 原矩阵列数
    for i in range(n):
        list2.append([])
    for i in range(n):
        for j in range(m):
            list2[i].append(list1[j][i])
    return list2

在写一行,列,对角线,反对角线。连续四个数相乘的函数,

#根据n的不同取值,求四种不同情况的四数的及成绩
def product(a,i,j,n):
    if n==0:
        return a[i][j]*a[i][j+1]*a[i][j+2]*a[i][j+3]#相邻行相乘
    if n==1:
        return a[i][j]*a[i+1][j]*a[i+2][j]*a[i+3][j]#相邻列相乘
    if n==2:
        return a[i][j]*a[i+1][j+1]*a[i+2][j+2]*a[i+3][j+3]#对角线相乘
    if n==3:
        return a[i][j]*a[i+1][j-1]*a[i+2][j-2]*a[i+3][j-3]#反对角线相乘
def arry0(a,n):
    #这是求任意列表组成数列求行的任意相邻n个数的和
    L1=len(a[0][:])#行数
    L2=len(a)#列数
    b=[]
    #c=[[0]*3]*3创建一个三维的列表,但是这样会造成预先那个不到的情况
    #比如c=[[],[],[]]与c=[[0]*3]*3不同,后者三个空列表相关联,但前者没有。
    for i in range(L2):
        for j in range(L1-n+1):
            b.append([product(a,i,j,0),i,j])
    return b
def arry1(a,n):
    #这是求任意列表组成数列求列的任意相邻n个数的和
    L1=len(a[0][:])
    L2=len(a)
    b=[]
    #c=[[0]*3]*3创建一个三维的列表,但是这样会造成预先那个不到的情况
    #比如c=[[],[],[]]与c=[[0]*3]*3不同,后者三个空列表相关联,但前者没有。
    for j in range(L2):
        for i in range(L1-n+1):
            b.append([product(a,i,j,1),i,j])
    return b
def arry2(a,n):
    #这是求任意列表组成数对角线任意相邻n个数的和
    L1=len(a[0][:])#行数
    L2=len(a)#列数
    b=[]
    #c=[[0]*3]*3创建一个三维的列表,但是这样会造成预先那个不到的情况
    #比如c=[[],[],[]]与c=[[0]*3]*3不同,后者三个空列表相关联,但前者没有。
    for i in range(L2-n+1):
        for j in range(L1-n+1):
            b.append([product(a,i,j,2),i,j])
    return b
def arry3(a,n):
    #这是求任意列表组成数反对角线任意相邻n个数的和
    L1=len(a[0][:])#行数
    L2=len(a)#列数
    b=[]
    #c=[[0]*3]*3创建一个三维的列表,但是这样会造成预先那个不到的情况
    #比如c=[[],[],[]]与c=[[0]*3]*3不同,后者三个空列表相关联,但前者没有。
    for i in range(L2-n+1):
        for j in range(L1-1,n-2,-1):
            b.append([product(a,i,j,3),i,j])
    return b

其实上面四个函数可以写一个函数,

def arry(a,n,m):
    if(m==0)or(m==1)or(m==2):
        L1=len(a[0][:])#行数
        L2=len(a)#列数
        b=[]
        #c=[[0]*3]*3创建一个三维的列表,但是这样会造成预先那个不到的情况
        #比如c=[[],[],[]]与c=[[0]*3]*3不同,后者三个空列表相关联,但前者没有。
        for i in range(L2-n+1):
            for j in range(L1-n+1):
                b.append([product(a,i,j,m),i,j])
    elif(m==3):
        L1=len(a[0][:])#行数
        L2=len(a)#列数
        b=[]
        #c=[[0]*3]*3创建一个三维的列表,但是这样会造成预先那个不到的情况
        #比如c=[[],[],[]]与c=[[0]*3]*3不同,后者三个空列表相关联,但前者没有。
        for i in range(L2-n+1):
            for j in range(L1-1,n-2,-1):
                b.append([product(a,i,j,m),i,j])
    return b
#求的四种情况的最大值
c1,c2,c3,c4=max(arry(a,4,0)),max(arry(a,4,1)),max(arry(a,4,2)),max(arry(a,4,3))
#求出这四个的最大值
print(max(c1,c2,c3,c4))
print(c1,c2,c3,c4)

这个问题有点难,不过对于list的理解也加深了很多。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值