1. 程式人生 > >求一個矩陣中連續四個數字(行,列,正、反對角線)乘積的最大值。

求一個矩陣中連續四個數字(行,列,正、反對角線)乘積的最大值。

最近在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的理解也加深了很多。