古生物血缘远近判定
DNA 是由 ACGT 四种核苷酸组成,例如 AAAGTCTGAC,假定自然环境下 DNA 发生异变的情况有:
基因缺失一个核苷酸
基因新增一个核苷酸
基因替换一个核苷酸
且发生概率相同。
古生物学家 Sam 得到了若干条相似 DNA 序列,Sam 认为一个 DNA 序列向另外一个 DNA 序列转变所需的最小异变情况数可以代表其物种血缘相近程度,异变情况数越少,血缘越相近,请帮助 Sam 实现获取两条 DNA 序列的最小异变情况数的算法。
例子如下:
输入:
- 每个样例只有一行,两个 DNA 序列字符串以英文逗号“,”分割
输出:
- 输出转变所需的最少情况数,类型是数字
输入:ACT,AGCT
输出:1
思路:
做一份表格,如下所示:
A | G | C | T | ||
---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | |
A | 1 | ||||
C | 2 | ||||
T | 3 |
然后,
如果格子对应的字符相同,则 p1 = 左上方格子的数值,如果不相同,则p1 = 左上方格子的数值+1
p2 = 左边格子数值 加一
p3 = 上方格子数值 加一
最后该格子的数值 = min(p1,p2,p3)
按照这个规则把表格填满,输出 最后一格的数值
【原理其实是按照题目要求的三个替换规则来设立的】
A | G | C | T | ||
---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | |
A | 1 | 0 | 1 | 2 | 3 |
C | 2 | 1 | 1 | 1 | 2 |
T | 3 | 2 | 2 | 2 | 1 |
输出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)−2K−1H(1)−2K−2H(2)−2K−3H(3)−2K−4H(4)−,,,2K−KH(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)−16−8−4>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)−16∗3−8∗4−4∗3−2∗2−1∗4=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))