华为20190525研发笔试

1. 判断两个ip是是否为同一网段

【题目描述】:
输入两个ip地址和一个子网掩码,判断这两个ip地址是否属于同一网段(ip地址与子网掩码按位与,结果相同)。
要求输出是否同一个网段(0否, 1是)和第一个ip与子网掩码按位与的结果

【输入描述】:
ip1 ip2 子网掩码(按空格隔开)

【输出描述】:
0或者1 第一个ip与子网掩码按位与的结果(用空格隔开)

【测试用例】:
【输入】:
192.168.1.1 192.168.1.2 255.255.255.0
【输出】:
1 190.168.1.0

解题思路:把ip与掩码的各个字段进行分离,按位与即可。在python中直接使用&就可以实现。

import sys
if __name__ == '__main__':
    # line = sys.stdin.split(" ")
    # ip1 = list(map(int, line[0].split(".")))
    # ip2 = list(map(int, line[1].split(".")))
    # mask = list(map(int, line[2].split(".")))
    ip1 = [192, 168, 1, 1]
    ip2 = [192, 168, 2, 1]
    mask = [255, 255, 255, 0]

    ip_res = []
    flag = 1
    for i in range(4):
        ip_res.append(ip1[i] & mask[i])
        if ip1[i] & mask[i] != ip2[i] & mask[i]:
            flag = 0

    print("{0} {1}.{2}.{3}.{4}".format(flag, ip_res[0], ip_res[1], ip_res[2], ip_res[3]))

2. 最大正方形全1矩阵

【题目描述】:
给定一个只包含01的矩阵,要求输出矩阵中最大正方形子矩阵的面积。(子矩阵中元素全部为1)

【输入描述】:
第一行: N 代表有几行
第1-N行: 01组成的字符串,每行的长度相同

【输出描述】:
返回一个数字, 代表输入矩阵的最大正方子矩阵的面积

【测试用例】:
【输入】:
4
10111
10111
11111
10010
【输出】:
9

解题思路:使用动态规划的思想,给出一个辅助矩阵temp。

原来的矩阵为:
m a t r i x = [ 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 ] matrix = \left[ \begin{matrix} 1 & 0 & 1 & 1 & 1 \\ 1 & 0 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 0 & 0 & 1 & 1 \\ \end{matrix}\right] matrix=11110010111011111111

构造一个与原矩阵一样大小的辅助矩阵temp。并把matrix的第一行和第一列赋值给temp。然后从第二行第二列开始遍历。

  1. 如果 m a t r i x [ i ] [ j ] = 0 matrix[i][j] = 0 matrix[i][j]=0, 则 t e m p [ i ] [ j ] = 0 temp[i][j] = 0 temp[i][j]=0
  2. 如果 m a t r i x [ i ] [ j ] = 1 matrix[i][j] = 1 matrix[i][j]=1, 则 t e m p [ i ] [ j ] = m i n ( t e m p [ i − 1 ] [ j ] , t e m p [ i ] [ j − 1 ] , t e m p [ i − 1 ] [ j − 1 ] ) + 1 temp[i][j] = min(temp[i-1][j], temp[i][j-1], temp[i-1][j-1])+1 temp[i][j]=min(temp[i1][j],temp[i][j1],temp[i1][j1])+1。表示以坐标(i,j)为右下角的最大正方形子矩阵的边长。
    t e m p = [ 1 0 1 1 1 1 0 1 2 2 1 1 1 2 3 1 0 0 1 2 ] temp = \left[ {\begin{matrix} 1 & 0 & 1 & 1 & 1 \\ 1 & 0 & 1 & 2 & 2 \\ 1 & 1 & 1 & 2 & 3 \\ 1 & 0 & 0 & 1 & 2 \\ \end{matrix}} \right] temp=11110010111012211232
    找到矩阵temp中最大的值就是最大正方形子矩阵的边长,最后输出边长的平方就是面积。
import sys
if __name__ == '__main__':
    N = int(sys.stdin.readline.strip())
    matrix = []
    for i in range(N):
        line = sys.stdin.readline.strip()
        matrix.append(list(map(int, line.split(" "))))
    
    # matrix = [[1, 0, 1, 1, 1],
    #           [1, 0, 1, 1, 1],
    #           [1, 1, 1, 1, 1],
    #           [1, 0, 0, 1, 0]]

    row, col = len(matrix), len(matrix[0])
    temp = [[0 for i in range(col)] for j in range(row)]

    # copy first row2
    temp[0] = matrix[0]
    # copy fitst col
    for i in range(row):
        temp[i][0] = matrix[i][0]

    maxlen = 0

    for i in range(1, row):
        for j in range(1, col):
            if matrix[i][j] == 1:
                temp[i][j] = min(min(temp[i-1][j], temp[i][j-1]), temp[i-1][j-1]) + 1
            else:
                temp[i][j] = 0

            maxlen = max(temp[i][j], maxlen)

    maxlen = max(maxlen, max(temp[0]))

    print(maxlen*maxlen)

3. 任务耗时

【题目描述】:
有m个并行处理器,n个任务(n>m),按照短作业优先进行调度,计算处理完所有任务的耗时。

【输入描述】:
m n  两个正整数,m是处理器的个数,n是任务数;用空格分隔
t1 t2 ... tn 每个任务的处理时长;用空格分隔

【输出描述】:
输出总处理时长

【测试用例】:
【输入】:
3 5
5 4 3 1 10
【输出】:
13

解题思路:

  1. 设置一个m大小的,用于执行任务的list: do_task。
  2. 每次从do_task中取出最小的处理时长,do_task中所有任务都减去这个最短时长,如果出现时长为0,则加入一个新的任务。每次累加这个最短时长。
  3. 直到任务list为空,表示所有任务都执行了。
  4. 判断最后的do_list,累加最大此时最大的处理时长,结果就是处理完所有任务的耗时。
import sys
if __name__ == '__main__':
    line = sys.stdin.readline.strip()
    m_n = list(map(int, line.slipt(" ")))
    m, n = m_n[0], m_n[1]
    line = sys.stdin.readline.strip()
    T = list(map(int, line.slipt(" ")))

    T.sort()
    res = 0
    do_task = [T.pop(0) for i in range(m)]

    while len(T) > 0:
        min_task = min(do_task)
        res += min_task
        for i in range(m):
            do_task[i] -= min_task
            if do_task[i] == 0:
                do_task[i] = T.pop(0)

    if len(do_task) > 0:
        res += max(do_task)

    print(res)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值