华为2021秋招,0819算法第一题(顺时针补入矩阵查找某个数的位置),python

题目
给你N行M列的人,他们是一个方阵。左上角是(0,0),右下角是(n-1, m-1),最外圈的人顺时针报数,当他们报的数个位是7并且十位是奇数,就选出来。外圈报完了内圈接着报,一直到所有人都报完,问最后选出来的是哪些。

要求是10<=n,m<=1000,如果输入不合法,那么就是返回空数组
输入
10 10
输出
[[7,9],[1,1],[8,2],[7,5],[4,4]]

思路:
一圈一圈的补,一共是(m+1)//2圈。每一圈分4部分补,比如1010的圈。第一部分是第一行的前9个,第二部分是最后一列的前9个,第三部分是最后行的后9个,第四部分是第一列的后9个。按这样的规则补。到第二圈是每部分补7个。第一三部分行上的补入个数n-(2i-1),第二四部分列上的补入个数是m-(2i-1)。第i圈的补入分别是第i-1行,第-i列,第-i行,第i-1列。第一部分补入的开始是a,第一个是1,第二部分补入开始是a+n-(2i-1),第三部分补入开始是a + m + n -2 (2i-1),第四部分补入开始是a + m + n + n - 3 * (2*i-1)。下一圈的a是上一圈最后一个数加1。有了这个矩阵,再去遍历矩阵,找符合要求数的位置。输出的时候不处理,会有空格,需要用list(str())删除里面的空格,再用join函数把拼起来,考试的时候就是没想起来怎么处理气死我。代码如下:

while True:
    try:
        list1 = list(map(int,input().split()))
        nn = list1[0]*list1[1]
        m = list1[0]
        n = list1[1]
        mm = min([(n+1)//2+1,(m+1)//2+1])
        a = 1
        dp = [[0 for _ in range(n)] for _ in range(m)]

        for i in range(1,mm):
            for i2 in range(n-(2*i-1)):
                dp[i-1][i2+i-1] = a + i2
                c = a + m + n -2 *(2*i-1)
                dp[-i][-i-i2] = c + i2
            for i3 in range(m-(2*i-1)):
                b = a + n - i*2+1
                dp[i3+i-1][-i] = b + i3
                d = a + m + n + n - 3 * (2*i-1)
                dp[-i3-i][i-1] = d + i3
            a = dp[i][i-1]+1
            print(dp)

        list2 = []
        for i3 in range(10,nn):
            list3 = list(str(i3))
            if len(list3)>=2:
                if int(list3[-1])==7 and int(list3[-2])%2==1:
                    list2.append(i3)
        list4 = []
        for i4 in list2:
            for i5 in range(m):
                if i4 in dp[i5]:
                    list4.append([i5,dp[i5].index(i4)])
        print(list4)
        list5 = list(str(list4))
        for i6 in list5:
            if ' 'in list5:
                list5.remove(' ')
        print(''.join(list5))
    except:
        break

你可能感兴趣的:(python)