刷Leetcode的第二十天--字节笔试题

古生物血缘远近判定
DNA 是由 ACGT 四种核苷酸组成,例如 AAAGTCTGAC,假定自然环境下 DNA 发生异变的情况有:
基因缺失一个核苷酸
基因新增一个核苷酸
基因替换一个核苷酸
且发生概率相同。

古生物学家 Sam 得到了若干条相似 DNA 序列,Sam 认为一个 DNA 序列向另外一个 DNA 序列转变所需的最小异变情况数可以代表其物种血缘相近程度,异变情况数越少,血缘越相近,请帮助 Sam 实现获取两条 DNA 序列的最小异变情况数的算法。
例子如下:

输入:
- 每个样例只有一行,两个 DNA 序列字符串以英文逗号“,”分割
输出:
- 输出转变所需的最少情况数,类型是数字
输入:ACT,AGCT
输出:1

思路:
做一份表格,如下所示:

AGCT
01234
A1
C2
T3

然后,
如果格子对应的字符相同,则 p1 = 左上方格子的数值,如果不相同,则p1 = 左上方格子的数值+1
p2 = 左边格子数值 加一
p3 = 上方格子数值 加一
最后该格子的数值 = min(p1,p2,p3)
按照这个规则把表格填满,输出 最后一格的数值
【原理其实是按照题目要求的三个替换规则来设立的】

AGCT
01234
A10123
C21112
T32221

输出1,即只需要一次改变

import sys
str_lis = sys.stdin.readline().strip().split(',') #生成字符串列表

str1 = list(str_lis[0])
str1 = [str(_) for _ in str1]

str2 = list(str_lis[1])
str2 = [str(_) for _ in str2]


N1 = len(str1)   #作为row 数
N2 = len(str2)   #最为 col数

#创建一个网格 
dp = [[float('inf')]*(N2+1) for _ in range(N1+1)]

for i in range(N1+1):
    dp[i][0] = i 
for j in range(N2+1):
    dp[0][j]= j 


for i in range(1,N1+1):
    for j in range(1,N2+1):
        if str1[i-1] == str2[j-1]:
            p1 = dp[i-1][j-1]
        else: p1 = dp[i-1][j-1]+1 

        dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, p1)

print(dp[N1][N2])

给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数

例子如下:

输入:[10,1,2]
输出:2110

输入:[3,30,34,5,9]
输出:9534330

ipt = input().strip()[1: -1].split(',')  #[1: -1]作用是去掉前后括号
tmp= [a+a for a in ipt]    #合并成两个 这个是为了避免当 30 和 3的比较 错误地 让30 作大
ans = []
for i in range(len(ipt)):
    index = tmp.index(max(tmp))
    ans.append(ipt[index])
    tmp.pop(index)  
    ipt.pop(index)
    #同时pop才能保证index的一致性
print(''.join(ans))

机器人正在玩一个古老的基于 DOS 的游戏。游戏中有 N+1 座建筑——从 0 到 N 编号,从左到右排列。编号为 0 的建筑高度为 0 个单位,编号为 i 的建筑的高度为 H(i) 个单位。
起初, 机器人在编号为 0 的建筑处。每一步,它跳到下一个(右边)建筑。假设机器人在第 k 个建筑,且它现在的能量值是 E, 下一步它将跳到第个 k+1 建筑。它将会得到或者失去正比于与 H(k+1) 与 E 之差的能量。如果 H(k+1) > E 那么机器人就失去 H(k+1) - E 的能量值,否则它将得到 E - H(k+1) 的能量值。
游戏目标是到达第个 N 建筑,在这个过程中,能量值不能为负数个单位。现在的问题是机器人以多少能量值开始游戏,才可以保证成功完成游戏

输入:
- 第一行输入,表示一共有 N 组数据.
- 第二个是 N 个空格分隔的整数,H1, H2, H3, ..., Hn 代表建筑物的高度
输出:
- 输出一个单独的数表示完成游戏所需的最少单位的初始能量
输入:
     5
     3 4 3 2 4
输出:4

输入:
     3
     4 4 4
输出:4

这里先弄清楚 跳跃的计算规则:
这里假设En表示能量值,Hn代表建筑物的高度.则有:
当H(k) > E(K-1):
E(K) = E(K-1) - (H(K)-E(K-1)) = 2E(K-1)-H(K)

当H(k) < E(K-1):
E(K) = E(K-1) + (E(K-1) - H(K)) = 2E(K-1) - H(K)

即,不管高度差如何,都有E(K) = 2E(K-1)-H(K)
而且这就是一个递归公式。
E(K) = 2E(K-1)-H(K) = 2( 2E(K-2)-H(K-1) ) - H(K)
= 4E(K-2) - 2H(K-1) - H(K) = 8E(K-3) - 4H(K-2) - 2H(K-1) - H(K)
即有:
E ( K ) = 2 K E ( 0 ) − 2 K − 1 H ( 1 ) − 2 K − 2 H ( 2 ) − 2 K − 3 H ( 3 ) − 2 K − 4 H ( 4 ) − , , , 2 K − K H ( K ) E(K) = 2^KE(0) - 2^{K-1}H(1) - 2^{K-2}H(2) - 2^{K-3}H(3) - 2^{K-4}H(4) - ,,,2^{K-K}H(K) E(K)=2KE(0)2K1H(1)2K2H(2)2K3H(3)2K4H(4),,,2KKH(K)
而我们知道 H(K), H(K-1), H(K-2),这些都是知道数值的,

所以,假设H数值为 [4 4 4]
那么,
E ( 3 ) = 2 3 E ( 0 ) − 2 2 H ( 1 ) − 2 1 H ( 2 ) − 2 0 H ( 3 ) = 8 E ( 0 ) − 16 − 8 − 4 > 0 E(3) = 2^3E(0) - 2^2H(1) - 2^1H(2) - 2^0H(3) = 8E(0) - 16 - 8 - 4 > 0 E(3)=23E(0)22H(1)21H(2)20H(3)=8E(0)1684>0
解得 E(0) > 3.5 即X=4

再来一个例子
假设H数值为[3 4 3 2 4]
E ( 5 ) = 2 5 E ( 0 ) − 2 4 H ( 1 ) − 2 3 H ( 2 ) − 2 2 H ( 3 ) − 2 1 H ( 4 ) − 2 0 H ( 5 ) > 0 E(5) = 2^5 E(0) - 2^4 H(1) - 2^3 H(2) - 2^2 H(3) - 2^1 H(4) - 2^0 H(5) >0 E(5)=25E(0)24H(1)23H(2)22H(3)21H(4)20H(5)>0
所以有:
E ( 5 ) = 32 E ( 0 ) − 16 ∗ 3 − 8 ∗ 4 − 4 ∗ 3 − 2 ∗ 2 − 1 ∗ 4 = 32 E ( 0 ) − 100 > 0 E(5) = 32E(0) - 16*3 - 8*4 - 4*3 - 2*2 - 1*4 =32E(0) - 100 > 0 E(5)=32E(0)16384432214=32E(0)100>0
所以 E(0) > 3.125, 所以E(0) = 4
代码如下:

import math
K = int(input().strip())
nums = list(map(int,input().split()))

N = len(nums)
sum_ = 0 
for i in range(1,N+1):
    sum_ += 2**(N-i) *nums[i-1] 

ans = (sum_/(2**N))
print(math.ceil(ans))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jianafeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值