2020阿里笔试 3月25号 第一题AC 第二题复原矩阵越想越变态

第一题 最小邻差绝对值求和

第一题AC,美滋滋

题目描述:

给定一个二维数组,3行n列,从每一列选择一个数,组成一个一维数组(1*N),对这个数组的邻差绝对值求和,保证这个和最小,输出这个最小的邻差绝对值的和。

输入描述:

第一行一个整数,代表n
接下来三行,代表二维数组矩阵
5
5 9 5 4 4
4 7 4 10 3
2 10 9 2 3

输出描述:

5

解释:

一维数组选为[5, 7, 5, 4, 4],邻差绝对值为2、2、1、0、0,和为5,所以输出5。

示例输入:

# 示例输入
5
5 9 5 4 4
4 7 4 10 3
2 10 9 2 3

示例输出:

5

思路:

动态规划
dp[i][j]表示在以arr[i][j]为结尾情况下的最小邻差绝对值求和结果

代码:

n = int(input().strip())
arr = [[0]*n for _ in range(3)]
for i in range(3):
    arr[i] = list(map(int, input().split()))
dp = [[0]*n for _ in range(3)]
dp[:][0] = 0                        # dp第一列全部置零
for lie in range(1,n):
    for hang in range(3):
        res1 = dp[0][lie - 1] + abs(arr[hang][lie] - arr[0][lie - 1])
        res2 = dp[1][lie - 1] + abs(arr[hang][lie] - arr[1][lie - 1])
        res3 = dp[2][lie - 1] + abs(arr[hang][lie] - arr[2][lie - 1])
        dp[hang][lie] = min(res1, res2, res3)
print(min(dp[0][-1], dp[1][-1], dp[2][-1]))

第二题 复原数独矩阵

第二题时间没够,考试结束后十分钟才码出来

题目描述:

给定一个矩阵n*m,每行每列都是等差数列,但是有部分值是被隐藏了的,数值为0即是被隐藏了。
根据输入的值i,j,判断这个位置上的值是否可以被推导出来,可以就输出,否则输出Unknown

输入描述:

第一行三个整数,代表n、m、q
接下来n行,代表二维数组矩阵A[n*m]
接下来q行,每行两个整数i,j,访问矩阵中的可能值A[i][j]

输出描述:

输出q行
若能推导出来对应位置的矩阵元素值,返回该值
若无法推导出来,返回Unknown

示例输入:

#示例输入
2 3 6
1 0 3
0 0 0
1 1
1 2
1 3
2 1
2 2
2 3

示例输出:

1
2
3
Unkown
Unkown
Unkown

思路:

复原矩阵
步骤:
1、按行复原矩阵
2、按列复原矩阵
3、再按行复原矩阵
4、再按列复原矩阵

代码:

def recover_hang():
    for hang in range(n):
        flag = 0
        i, i_val, j, j_val = -1, 0, -1, 0
        for lie in range(m):
            if A[hang][lie]:
                flag += 1
                if i == -1:
                    i, i_val = lie, A[hang][lie]
                elif j == -1:
                    j, j_val = lie, A[hang][lie]
        if flag >= 2:
            for lie in range(m):
                A[hang][lie] = A[hang][i] + int((j_val - i_val) / (j - i) * (lie - i))
def recover_lie():
    for lie in range(m):
        flag = 0
        i, i_val, j, j_val = -1, 0, -1, 0
        for hang in range(n):
            if A[hang][lie]:
                flag += 1
                if i == -1:
                    i, i_val = lie, A[hang][lie]
                elif j == -1:
                    j, j_val = lie, A[hang][lie]
        if flag >= 2:
            for hang in range(n):
                A[hang][lie] = A[hang][i] + int((j_val - i_val) / (j - i) * (lie - i))

n,m,q = list(map(int,input().split()))
A = [[0]*m for _ in range(n)]
Q = [[0]*2 for _ in range(q)]
for i in range(n):
    A[i] = list(map(int, input().split()))
for i in range(q):
    Q[i] = list(map(int, input().split()))

recover_hang()
#print(A)
recover_lie()
#print(A)
recover_hang()
#print(A)
recover_lie()
#print(A)
for i in range(q):
    if A[Q[i][0]-1][Q[i][1]-1] == 0:
        print('Unkown')
    else:
        print(A[Q[i][0]-1][Q[i][1]-1])

分隔线


第二题复原矩阵,才发现我想的太简单了。还是漏掉了一种情况。
如果四个点都不在同一行或者同一列,就足够复原出整个矩阵了。例如

[0100000110000010] \begin{gathered} \begin{bmatrix}0& 1& 0& 0\\0 &0 &0 &1\\1& 0& 0& 0\\ 0& 0& 1 &0\end{bmatrix} \end{gathered}
可以证明,该矩阵可以复原,且矩阵唯一,是全1矩阵。
设中间四个元素为未知变量,可列四个线性方程,四个未知数。
[01000x1x211x3x400010] \begin{gathered} \begin{bmatrix}0& 1& 0& 0\\0 &x_1 &x_2 &1\\1& x_3& x_4& 0\\ 0& 0& 1 &0\end{bmatrix} \end{gathered}
可以证明方程之间是线性无关的,所以可解。
然后再用行列行或者列行列就可以复原出整个矩阵。
解四元一次线性方程组的代码很麻烦了,考试时间这么短也很难敲出来吧。
备注:
如果是四阶单位矩阵

[1000010000100001] \begin{gathered} \begin{bmatrix}1& 0& 0& 0\\0 &1 &0 &0\\0& 0& 1& 0\\ 0& 0& 0 &1\end{bmatrix} \end{gathered}
应该是复原不了的,因为可以是
[11+a1+2a1+3a1a11+a1+2a12a1a11+a13a12a1a1] \begin{gathered} \begin{bmatrix} 1 & 1+a & 1+2a & 1+3a \\ 1-a & 1 & 1+a & 1+2a \\ 1-2a &1-a &1 & 1+a \\ 1-3a & 1-2a& 1-a& 1\end{bmatrix} \end{gathered}

这题真的是很变态了。

感谢以下同学提供的思路、指正以及交流经验:(博客昵称)

1、weixin_38390663
2、闲不下来的王小C
3、August-us

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值