阿里巴巴2018实习生-算法工程师笔试题1

题目1描述:

八卦阵相传是由诸葛亮创设的一种战斗队形和兵力部署,由八种阵势组成。为了方便,采用矩阵来描述一个八卦阵,它由八个单阵组成,每个单阵由多个兵力区域组成形成一种阵势,如下图所示,其中数字为一个兵力区域的士兵个数。假设单阵与单阵之间兵力区域不会相邻,且单阵中每个兵力区域至少存在一个相邻兵力区域(注:相邻是指在其左上,正上,右上,右方,右下,正下,左下,左方与其相邻),请用最快的速度计算出八个单阵中的兵力(士兵个数)的最大值和最小值。

数据如下图:

阿里巴巴2018实习生-算法工程师笔试题1_第1张图片

题目分析:

广度优先搜索用队列实现,每次进队,就进行累计兵力数。这个题目应该非常简单,但是没做,被这个大矩阵和一大段文字看懵了,直接做的第二道题目,肠子悔青呀,不可浮躁

Python3实现:

# 阿里巴巴2018实习生-算法工程师附加卷-编程题1(笔试时间2018-05-11 19:30)
# 解题思路 广度优先搜索,用队列实现,每次进队,就进行累计兵力数
# @Time   :2018/5/12
# @Author :LiuYinxing


def getSum(i, j, n, m, maps):  # [i, j]单阵入口,[n,m]矩阵维度数,maps矩阵
    queue, sump, maps[i][j] = [[i, j]], maps[i][j], 0  # 初始化队列
    while queue:
        x, y = queue[0][0], queue[0][1]  # 获取队列头元素
        for dx, dy in zip((-1, -1, 0, 1, 1, 1, 0, -1), (0, 1, 1, 1, 0, -1, -1, -1)):  # 8个方向
            nx, ny = x + dx, y + dy
            if -1 < nx < n and -1 < ny < m and maps[nx][ny] != 0:
                queue.append([nx, ny])  # 入队
                sump += maps[nx][ny]  # 累计兵力
                maps[nx][ny] = 0  # 累计过的单个区域兵力为0
        del queue[0]  # 出队
    return sump  # 返回单阵的兵力总和


if __name__ == '__main__':
    maps = [[34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 30],
            [0, 23, 10, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 30, 0, 40, 0],
            [0, 9, 0, 0, 5, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 30, 0, 0],
            [0, 8, 7, 7, 0, 5, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 7, 0, 9, 0],
            [0, 9, 0, 0, 5, 0, 5, 0, 0, 12, 12, 0, 0, 0, 0, 10, 0, 0, 0, 9],
            [0, 0, 0, 0, 5, 0, 0, 5, 0, 12, 12, 0, 0, 5, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 5, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0],
            [40, 30, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 10, 0],
            [0, 0, 20, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 5, 6, 5, 10, 10, 0],
            [40, 30, 3, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 10, 0],
            [0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 17, 0, 0, 6, 5, 7, 7, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 20, 0, 0, 7, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0],
            [0, 20, 0, 0, 7, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0],
            [0, 20, 0, 0, 7, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 10, 0, 0, 0],
            [0, 30, 0, 7, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 10, 0, 50],
            [0, 40, 7, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 50, 0],
            [43, 30, 25, 10, 50, 0, 0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0, 50, 0, 0]]
    n, m = 20, 20  # 输入行列
    army = []
    for i in range(20):
        for j in range(20):
            if maps[i][j] != 0: army.append(getSum(i, j, n, m, maps))  # 获取每个单阵的兵力和

    smax, smin = float('-inf'), float('inf')  # 获取最大和最小值
    for v in army:
        if v > smax: smax = v
        if v < smin: smin = v
    print('每个单阵兵力和:', army)
    print('单阵兵力最多为:', smax)
    print('单阵兵力最少为:', smin)

发现问题,记得留言指教哦。

你可能感兴趣的:(算法,Python)