笔试算法-编程练习-01-J-24

d这套题,第一题数学找规律、第二题也是掺杂一些数学的模拟、第三题是动态规划。整体题目代码量不大,但是比较灵活,考验思维的敏捷度。


一、下雪

题目描述

村子里有一些桩子,从左到右高度依次为1,1+2,1+2+3,…,每两颗桩子之间的间隔为1。

现在下了一场大雪,但是不知道雪下了多厚,现在给你两个数字,这是雪后某相邻两个桩子在雪面的高度,请你通过这两个数字计算雪的厚度。

输入描述

第一行输入两个整数a,ba,b

1≤a<b≤5∗1051≤a<b≤5∗10​5​​

输出描述

一个整数代表答案,保证答案存在

样例

输入

8 13

输出

2

说明

高度依次是1,3,6,10,15,.给出的是第4个和第5个子雪面上的高度所以雪的厚度是2

输入

10 15

输出

0

题目分析:

两个柱子的高度差是不变的,高度差就是第二个柱子的序号。因此求得第二个柱子的正常高度再减去当前的高度就是雪的厚度

代码:

temp_in = input().split()
a, b = int(temp_in[0]), int(temp_in[1])
d = b-a
result = int(((1+d)*d)/2 - b)
print(result)

二、积木

题目描述

牛牛有一种锯齿状的积木,这种积木比较长,但是每个单位长度的高度是相等的高度为 1 或者 2。

现在牛牛拿出了两块长度分别为n和 m 的积木,她现在想把这两块积木拼接在起,即使中间有空隙也没有关系。

但是拼接后的积木的高度要不超过 3,请你帮助牛牛计算在满足这个前提下拼接后的积木的长度最短可以是多少。

输入描述

第一行给出两个正整数 n,m,代表第一块和第二块积木的长度

第二行给出 n 个数字代表第一块积木每个单位的高度

第三行给出 m 个数字代表第二块积木每个单位的高度 1≤n,m≤10001≤n,m≤1000

输出描述

一个整数,表示拼接后的积木的最短长度

样例

输入

7 10
2212112
2112112112

输出

10

输入

3 2
222
22

输出

5

题目分析:

两个积木拼接起来的最大长度是m+n,核心思想是不可以在同一个位置同时出现‘2’。

实现方案是先记录两个字符串中所有'2'的索引为m_2,n_2;我们保持积木n不动,移动m来拼接积木,构建一个record数组,用来存储积木m的头元素可以存在的位置。根据m_2和n_2中的索引,我们可以计算出积木m的头不可以出现的位置,我们将这些位置刨除。最后计算每种情况的拼接长度,保存最小值即可。

但这里存在一个问题,因为该题的背景描述为拼积木,那么默认积木是可以随机翻转的,因此我的代码中包含了翻转的过程。但是实际测评中好像是不翻转(即,翻转代码会导致测评不满分)

代码:

temp_in = input().split()
n, m = int(temp_in[0]), int(temp_in[1])
s_n = input().split()[0]
s_m = input().split()[0]

def calc(n, m, s_n, s_m):
    result = m+n
    m_2 = [idx for idx, c in enumerate(s_m) if c == '2']

    for i in range(2):
        # 积木n 正向/反向 两种情况
        if i == 1:
            s_n = s_n[::-1]
        n_2 = [idx for idx, c in enumerate(s_n) if c == '2']
        
        # 构造一个m+n+1的空间用来存储本次可以成功拼接的情况
        # 字符串n不动,只移动m,记录m的第一个字符的位置
        record = [ _ for _ in range(m+n+1)]
        for m_i in m_2:
            for n_i in n_2:
                temp_idx = m + n_i - m_i
                record[temp_idx] = -1

        # 计算每种拼接情况的总长度
        for idx in record:
            if idx != -1:
                temp_ans = m+n
                if idx < m:
                    temp_ans = max(m, m-idx+n)
                else:
                    temp_ans = max(n, idx)
                if temp_ans < result:
                    result = temp_ans    
        
    return result
print(calc(n, m, s_n, s_m))

三、过年

题目描述

牛牛也是要回家过年的呢。

牛牛所在的国家有 n 座城市,m 条有向道路,第 i 条道路由城市ui​​通往城市v​i​​,通行费为 wi​​。

作为一头豪气的牛,希望他回家的花费是一个特殊的数字(例如666元)。具体的说,牛牛希望从城市1移动到城市n,并恰好花费a元。

请你告诉牛牛,他有多少种回家的方案?

输入描述

第一行三个整数n,m,a(1≤n≤100,1≤m≤1000,1≤a≤1000),含义如题面所示。 接下来mm行,第ii行三个整数 u_i,v_i, w_i(1 ≤ u_i,v_i \le n,1≤ w_i ≤ a),描述了一条道路。

输出描述

如果牛牛回家的方家数大于等于 20220201种,请你在第一行输出A1l roads lead to Home!,然后在第二行输出回家的方案数对 20220201 取模的结里

否则只需要输出一行一个整数,表示牛牛回家的方案数。

样例

输入

3 6 2
1 2 1
1 2 1
1 2 1
2 3 1
2 3 1
2 3 1

输出

9

说明

从城市一到城市二有3种不同的走法,从城市二到城市三也有3种不同的走法,根据乘法原理我们可以知道,一共有3x3=9种不同的回家方法。

题目分析:

这类计算图中a点到b点有多少种可能性的题目,优先考虑动态规划。本题我们需要考虑一个二维的动态转移数组,dp[i][s],表示到达点i花费为s的方式的数量,这个值如何计算呢?假设我们遍历i的前序节点,其中任一一个节点描述为j,点j到点i的花费为w的路有cnt条,那么我们遍历所有的j和w即可:dp[i][s] = sum(dp[j][s-w]*cnt)。在实际操作中cnt和w可以存在图中,下面代码里我们用了多层dict来描述图的数据结构。

注意:遇到这类题不要上来就dfs或者模拟,通常都不是最优方法,先尝试写一下状态转移方程。

代码:

temp_in = input().split()
n, m, a = int(temp_in[0]), int(temp_in[1]), int(temp_in[2])

G = {}
for _ in range(m):
    try:
        temp_in = input().split()
        # 构造G
        v, u, w = int(temp_in[0]), int(temp_in[1]), int(temp_in[2])
        # G[u][v][w]:表示 从 [v] 点指向 [u] 点花费为 [w] 的路的 【数量】
        if u in G.keys():
            if v in G[u].keys():
                if w in G[u][v].keys():
                    G[u][v][w] += 1
                else:
                    G[u][v][w] = 1
            else:
                G[u][v]={w:1}
        else:
            G[u] = {v:{w: 1}}
    except:
        break

# print(G)
# for k in G.keys():
#     print(k, G[k])
    
dp = [ [ 0 for _ in range(a+1)] for _ in range(n+1) ]
dp[1][0] = 1
# 转移方程:dp[i][s] += sum(dp[j][s-w] * G[i][j][w])      sum中需要遍历i的每个前序点j的每种花费
for s in range(1, a+1):
    for i in range(1, n+1):
        if i in G.keys():
            for j in G[i].keys():
                for w in G[i][j].keys():
                    if s - w >= 0:
                        dp[i][s] += dp[j][s-w]*G[i][j][w]
                    

if dp[n][a] >= 20220201:
    print("All roads lead to Home!")
    dp[n][a] %= 20220201

print(dp[n][a])

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于准备嵌入式校招笔试的同学来说,以下几点是需要注意的: 1. 刷题是必须的,尽早开始刷题,最好在4-5月就开始了。可以从LeetCode的初级算法刷起,然后逐渐进阶到中级算法。建议刷题过程中做好刷题笔记,方便后期的快速回顾。同时,牛客网也是一个不错的刷题平台,因为很多公司的笔试就在牛客网进行。要注意牛客网需要自己处理输入输出的问题。 2. 刷题要重质量而不是数量。建议刷题三遍,第一遍不会做的话可以看答案,然后自己理解并重新写一遍;第二遍尽可能自己写,如果实在写不出来可以再看答案,并继续写;第三遍尽可能独立完成。刷题过程中,可以针对不擅长的题型进行针对性练习。 3. 复习数据结构是很重要的,最好在刷题前大概复习一下数据结构,否则可能会看不懂答案。 4. 推荐关注公众号“labuladong”,里面有很好的算法解析,特别是二分法、滑动窗口、双指针和二叉树等方面的内容。 5. 在刷题过程中,最好使用C语言,因为很多面试中会用到C语言的相关知识。尤其是C语言的STL库,如哈希表、链表、数组等容器,在刷题过程中非常方便。 综上所述,嵌入式校招笔试的选择题准备建议包括刷题、做好刷题笔记、复习数据结构、关注算法解析公众号、使用C语言等。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [2021年嵌入式校招求职经历](https://blog.csdn.net/qq_39887918/article/details/124039941)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值