2020年3月25日阿里笔试题

  • 题目描述一
    • python代码
  • 题目描述二
    • 求公差的python代码
    • 处理上述情况的代码

  仿佛人生总有一种魔咒,自己做的这场笔试题永远是最难的。不过今天的笔试题,真的难。来看题目。

题目描述一

给定一个数组长度n,然后给三个长度为n的数组,可以从这三个数组中选出一个长度为n的数组,第i个位置需要是从给出的三个数组第i个位置选择的,然后要求使这个数组后一项减前一项的绝对值之和最小。
输入示例:
5
5 9  5 4  4
4 7  4 10 3
2 10 9 2  3
这里可以选择5 7 5 4 4,所以输出等于|7-5|+|5-7|+|4-5|+|4-4|=5。所以输出就是5。

  一到考试有点慌,知道要用动态规划,然后就想怎么用。这个问题可以看成是在矩阵中寻找一个路径,要求整个路径的前向之差绝对值最小。可以想如何把问题规模缩小,显然下一个数的选择,可以有三条路径,如果从第一行过来,那么就需要用到选了第一行的路径的和的最小值,同样也需要求出用到第二行和第三行过来的路径的最小值。
  可见这是一个动态规划问题。我们定义一个动态规划数组,dpijdp_{ij}dpij​表示选择了矩阵中(i,j)位置的元素,最小的路径绝对值之和。显然最终的结果就是最后一列三个路径最小值。
  dpij=min(abs(A[i][j]−A[i−1][k])+dpi−1,k)k∈0,1,2dp_{ij}=min(abs(A[i][j]-A[i-1][k])+dp_{i-1,k}) \quad k\in{0,1,2}dpij​=min(abs(A[i][j]−A[i−1][k])+dpi−1,k​)k∈0,1,2
  好了,有公式可以写代码了。我直接给出我的AC代码,尴尬的就是直接想把时间复杂度和空间复杂度写到最小。(完美主义害死人,在这里多花了几分钟的时间。)

python代码

n=int(input())
a1=[int(i) for i in input().split(' ')]
a2=[int(i) for i in input().split(' ')]
a3=[int(i) for i in input().split(' ')]
A=list(zip(a1,a2,a3))
pre=[a1[0],a2[0],a3[0]]
minsum=[0,0,0]
preSum=[0,0,0]for i in range(1,n):for row in range(3):# 这行代码表示对上面的公式取最小值。minsum[row]=min([preSum[num]+abs(A[i][row]-A[i-1][num]) for num in range(3)])# 为了节省空间,我没有开辟一个和输入数组一样大的空间。preSum=minsum.copy()
print(min(minsum))

  虽然有一次AC的成就感,但是做完这个题,已经快四十分钟过去了,第二题我还没看。谁知道第二题,依旧非常难。

题目描述二

给出一个二维矩阵,这个矩阵的每一行和每一列都是一个独立的等差数列,其中一些数据缺失了,现在需要推理隐藏但是可以被唯一确定的数字,然后对输入的查询进行回答。

输入描述:
第一行,n,m,q分别表示矩阵的行数,列数和查询的条数。
接下来的n行,每行m个数表示这个矩阵,0表示缺失数据。−109≤Aij≤109-10^9≤A_{ij}≤10^9−109≤Aij​≤109
接下来q行,每行两个数字i,j表示对矩阵中第i行第j列的数字进行查询。

输出描述:
如果可以确定该位置的数字,则输出数字,如果不能确定则输出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
Unknown
Unknown
Unknown

  这个题目有点变态,我没有想出什么好办法,提交的代码也有bug,结束后做一做这个题目的分析。根据题意,如果一个矩阵中可以确定两行或者两列就可以完全确定这个矩阵。如何确定两行或者两列呢,这两行和这两列必须有两个以上的数字。如果有两个以上的数字,则可以对这行或列求出公差,整行或列就可以确定。
  所以我觉得求出公差是比较关键的一步,我的代码直接奔着求出公差去了。一旦求出公差,则只需要保存该行或者列的一个数就可以确定整行整列。下面看我求出公差的代码。
  这里补充解释一下为什么我要求公差,因为求出来公差确定这行肯定是已知的,所以即便本来有元素就是0,那么也可以正确返回。但是如果不求出公差的话,检索到这个位置是0,无法判断是否是Unknown还是本来就是0。

求公差的python代码

n, m, q = [int(i) for i in input().split(' ')]
A = []
Q=[]
for i in range(n):A.append([int(i) for i in input().split(' ')])
for i in range(q):Q.append([int(i) for i in input().split(' ')])
row=[0]*n  # 求行的公差
col=[0]*m  # 求列的公差
numRow=[-1]*n # 求该行的一个数的索引
numCol=[-1]*m # 求该列的一个数的索引
for i in range(n):for j in range(m):if A[i][j]:p=jnumRow[i]=jfor j in range(j+1,m):if A[i][j]:row[i]=(A[i][j]-A[i][p])//(j-p)for j in range(m):if not A[i][j]:A[i][j]=A[i][numRow[i]] + ((j - numRow[i]) * row[i])breakbreak
for i in range(m):for j in range(n):if A[j][i]:p = jnumCol[i]=jfor j in range(j + 1, n):if A[j][i]:col[i]=(A[j][i]-A[p][i])//(j-p)for j in range(n):if not A[j][i]:A[j][i]=A[numCol[i]][i] + ((j - numCol[i]) * col[i])breakbreak# print(A)
for i,j in Q:i=i-1j=j-1if row[i] or col[j] or A[i][j]:print(A[i][j])else:print('Unknown')

  如果不能计算出整个矩阵的话,我的代码到这也就结束了。但是我提交的时候,时间结束了,bug还没有修复,这个代码也没有得到验证。
  后来在网上找到别人的实现,证明这样做是对的。但是这样是对的只能说明一个问题,那就是阿里的测试用例有问题,举个四个数可以确定整个矩阵,但是上面的代码无法确定整个矩阵的的情况。

4 5 0 0
9 0 0 0
0 0 24 0
0 0 0 0

  让上面的代码跑一遍,还是会有很多的空洞,我们看这些空洞,很容易想到把代码再跑一遍就可以把整个矩阵填充完整。下面是跑两遍,可以解决这种情况的代码。此处更正我的一个错误,之前说过不需要在记录公差,事实上还会遇到不可解的情况和此处为0的情况同时出现出现。所以这里还是需要记录公差是否可求,而且求出来的公差可能是0的情况,所以记录公差用公差的值做判断也有瑕疵的,我下面更正成了记录公差是否可求。

处理上述情况的代码

n, m, q = [int(i) for i in input().split(' ')]
A = []
Q = []
for i in range(n):A.append([int(i) for i in input().split(' ')])
for i in range(q):Q.append([int(i) for i in input().split(' ')])
row=[False]*n  # 记录该行是否公差可求
col=[False]*m  # 记录该列是否公差可求
for time in range(2):for i in range(n):for j in range(m):if A[i][j]:p = jfor j in range(j + 1, m):if A[i][j]:d = (A[i][j] - A[i][p]) // (j - p)row[i]=Truefor j in range(m):if not A[i][j]:A[i][j] = A[i][p] + ((j - p) * d)breakbreakfor i in range(m):for j in range(n):if A[j][i]:p = jfor j in range(j + 1, n):if A[j][i]:d = (A[j][i] - A[p][i]) // (j - p)col[i]=Truefor j in range(n):if not A[j][i]:A[j][i] = A[p][i] + ((j - p) * d)breakbreak
for a in A:print(a)for i, j in Q:if row[i-1] or col[i-1] or A[i-1][j-1]:# 如果行或列的公差可求,该数一定可求。print(A[i-1][j-1])else:print('Unknown')

  但是上面的代码还是有瑕疵的,最少有四个点就可以求出整个矩阵,因为这个行和列的等差数列矩阵秩是小于2的。而且可以证明,行和列的公差也是个等差数列,而这个时候我们称之为二阶公差,行和列的二阶公差是相等的。感谢我的师兄的讨论,和给我的启发。
  举个四个数可以确定整个矩阵,但是无法求出任何一个行或列的公差的情况。这个题可以利用行的二阶公差和列的公差相等。把四个点带进去,列一个线性方程组求解,具体细节不再这里展开。

4 0 0 0
0 0 0 18
0 0 24 0
0 26 0 0

  代入线性方程组可以解出来整个矩阵,但是这可能是线性代数的内容了,如果编程题这样出,我觉得不太可能。不过用上述两个代码跑这个实例,根本解不出这个矩阵,因为四个点都不在同一行或者同一列,上面的代码无法求出任何一个公差,所以认为这是不可解的(实际可解)。这里给出一个证明结论,如果四个点中有三个点来自于一行(或一列),则无法解出这个方程组。如果四个点,两个点是一行,另外两个点在一列上,也是无法解出这个矩阵。

2020年3月25日阿里笔试题相关推荐

  1. 2020年3月23日阿里笔试题

    2020年3月23日阿里笔试题 题目描述 题目分析   这是阿里的第二场笔试,本来觉得没啥好写的,一道排列组合,一道迷宫.没有什么发挥的空间.但是后来在和大家讨论的过程中,把这道题的公司给敲出来了,但 ...

  2. 2020年9月25日-01-项目启动(团队分工)+带宽,网络速度的计算

    此博客用于记录2020年9月25日每日分享, 大概讲讲团队里的分工合作那些事儿. 关于带宽啊,网速啊之类的一些事儿 日期:2020年9月25日 主题: 团队合作怎么合作?有什么人?一般用什么工具?诸如 ...

  3. GOE:Nintendo Switch™ 对战忍者口香糖动作游戏 『Ninjala』决定于2020年6月25日发售

    东京--(美国商业资讯)--GungHo Online Entertainment, Inc.(TOKYO:3765)官方宣布,Nintendo Switch™对战忍者口香糖动作游戏『Ninjala』 ...

  4. 【财经期刊FM-Radio|2020年09月25日】

    [财经期刊FM-Radio|2020年09月25日] 微信公众号: 张良信息咨询服务工作室 [今日热点新闻一览↓↓] 要闻: 欧股创三月新低,美股大震荡最终惊险收涨,期银抹平6%跌幅转涨,天然气两日高 ...

  5. 【财经期刊FM-Radio|2020年11月25日】

    title: [财经期刊FM-Radio|2020年11月25日] 微信公众号: 张良信息咨询服务工作室 [今日热点新闻一览↓↓] 道指首次升破3万点,原油比特币高涨,金银再跌,特斯拉盘中市值突破50 ...

  6. 洛奇 服务器文件,《洛奇》2020年5月25日合服改名服务公告

    由于上周技术故障导致合服页面未能开放成功,此前进入的玩家改名数据未能写入,因此定于今日16:00重新开启改名页面 以下玩家可通过自助改名服务页面进行登记改名: 原玛丽服务器合服后角色名/宠物名变为XX ...

  7. 今日新闻大事件 2020年11月25日 星期三

    今日新闻大事件汇总,热点新闻简短汇总,就在365资讯简报,每日推送12条新闻大事件和一条励志语录.60s读懂世界 [365资讯简报]每天一分钟,知晓天下事! 2020年11月25日 星期三 农历十月十 ...

  8. 神雕侠侣服务器维修时间,《神雕侠侣》2020年6月25日更新维护新服开启公告

    亲爱的玩家: 为了给您提供更好的游戏体验,我们将于2020年6月25日上午8:00-11:00对所有服务器进行停机更新维护,预计维护时间3小时. 若提前完成维护内容,我们将提前开服.对于停机期间给您带 ...

  9. 21-0003 2020年3月25日的面试,开发岗位遇到的题目

    面试中遇到的问题 1.简历投递情况 2.知识掌握情况 2.1 C++ 2.2 Unity 3d 3.笔试面试情况 3.1 北京庚图 3.2 华为 3.3 三七互娱 4.个人现状 1.简历投递情况 前言 ...

最新文章

  1. 百分点首席经济学家张忠解读《美国白宫大数据白皮书》
  2. [3/21]Windows Server 2008时钟方面的改进展示
  3. honeywell新风系统控制面板说明_详解装了新风系统,怎么清洗维护简单?
  4. 亲,你们都在家办公吗?啥感受?hahaha
  5. python字符串重复输出例子_使用python语言,比较两个字符串是否相同的实例
  6. pandas筛选某个列值是否位于某个列表内
  7. Lua中handler方法的使用(亲测版)
  8. 电子申请客户端(EAC)在64位系统上的兼容性问题
  9. IM即时通讯实现原理
  10. City2vec:一种学习人口迁徙网络知识的新方法
  11. 计算机专业核心基础学习路线!
  12. MySQL的日志 - relay log
  13. angularJS简介
  14. Centos配置Web Proxy(nginx)
  15. 13个适合上班时做的保健小动作
  16. 记录一次搭建家用小型服务器的经历
  17. Drools学习笔记4-第一个例子
  18. 数据仓库和数据库的区别
  19. 12种数据量纲化处理方式
  20. 计算机地质模拟,地质过程计算机模拟.ppt

热门文章

  1. 60个超实用的生活小常识!
  2. Spring参数解析器
  3. touch pro2 T7373 直刷 安卓2.2
  4. 软件工程实践专题 第一次作业
  5. java最好用的json工具_推荐 9 个 爱不释手的 JSON 工具!
  6. 个人自用总结的Android模块化架构模板
  7. python中globals()_python中globals()的原因是什么?
  8. ABP+AdminLTE+Bootstrap Table权限管理系统第十一节--bootstrap table之用户管理列表
  9. 量子化学--分子动力学
  10. 内网穿透的实现和原理解析