今日复习内容:重做一遍复习题(一部分)
例题1:小蓝的漆房
题目描述:
小蓝是一位有名的漆匠,他的朋友小桥有一个漆房,里面有一条长长的走廊,走廊两旁有许多相邻的房子,每间房子最初被涂上了一种颜色。
小桥来找小蓝,想让他把整个走廊都涂成一个颜色。小蓝告诉小桥,他每天只能涂一段长度为k的区间。对于每个区间,他可以选择将其中的房子重新涂上任何一种颜色,或者保持原来的颜色不变。
小桥想知道小蓝至少要涂几天,才能让整个走廊都变得努力。
请帮助小桥解决这个问题。
输入格式:
第一行包含一个整数t(1 <= t <= 100),表示测试用例的数量。
每个测试用例的第一行包含两个整数n和k(1 <= k <= n <= 10^4),第二行包含n个整数a1,a2,...,an(1 <= ai <= 60),分别表示每个房子最初的颜色。
保证所有测试用例n的总和不超过10^4。
输出格式:
对于每个测试用例,输出一个整数,表示小蓝需要涂漆的最少天数。
参考答案:
t = int(input())
for i in range(t):
n,k = map(int,input().split())
a = list(map(int,input().split()))
res = 1e9
for i in range(1,61):
cnt = 0
j = 0
while j < n:
if a[j] != i:
cnt += 1
j += k
else:
j += 1
res = min(res,cnt)
print(res)
运行结果:
我来记录一下我做这道题时的思路:
这段代码解决了小桥面临的问题,即确定在每天只能涂一段长度为k的情况下,小蓝至少需要涂漆的最少天数。以下是我写每一行代码 的思路(这仅仅是本人观点)
1.输入处理
t = int(input()):输入测试用例的数量
for i in range(t):遍历每个测试用例
n,k = map(int,input().split()):输入每个测试用例中走廊长度n和每天涂漆的长度k
a = list(map(int,input().split()):输入每个房子最初的颜色
2.寻找最少涂漆天数
res = 1e9:初始化一个变量res用于存储最少涂漆天数,初始值设置为一个很大的数
for i in range(1,61):遍历颜色编号,因为每个房子的颜色范围是1到61
cnt = 0:初始化一个计数器,用于统计涂漆的次数
j = 0:初始化一个指针,指向当前走廊的位置
while j < n:遍历整个走廊
if a[j] != i:如果当前房子的颜色不等于当前颜色编号i
cnt += 1:增加涂漆的次数
j += k:跳到下一个涂漆区间的初始位置
else:如果当前房子的颜色等于当前颜色编号i
j += 1:移动到下一个房子
res = min(res,cnt):更新最小涂漆天数,选择最小值
3.输出结果
print(res):输出每个测试用例中小蓝需要涂漆的最小天数
这段代码的关键是通过遍历可能的颜色,统计在每个颜色下涂漆的次数,然后选择涂漆次数的最小值作为最少涂漆天数。这样的遍历方式确保了每次都考虑了以不同颜色为基准的涂漆情况,最终得到了最优解。
例题2:小蓝和小桥的挑战
题目描述:
小蓝和小桥是游戏世界里的几个好友,他们正在玩一个有趣的挑战。他们手中有一个长度为n的神秘物品序列,每个物品都有一个数字ai表示他们的价值。他们可以执行以下操作:
选择一个物品,并将它们的价值加1。
小蓝和小桥希望通过若干次操作使得这个序列的价值之和与价值之积都不为0。
请你帮他们计算,至少需要执行多少次操作才能完成这个挑战。
输入格式:
第一行包含一个整数t(1 <= t <= 100),表示测试用例的数量。
接下来t行,每行包含两行数据,第一行为一个整数n(1 <= n <= 1000),表示物品的数量。第二行包含n个整数a1,a2,a3,...,an(-1000 <= ai <= 1000),表示初始的物品价值。
输出格式:
对于每个测试用例,输出一行一个整数,表示至少需要执行的操作次数。
参考答案:
t = int(input())
for i in range(t):
n = int(input())
li = list(map(int,input().split()))
ans = 0
cnt = 0
for i in range(n):
if li[i] == 0:
li[i] += 1
cnt += 1
ans += li[i]
if ans == 0:
cnt += 1
print(cnt)
运行结果:
我来记录一下我写这段代码的思想(仅为本人观点)
1.输入处理
t = int(input()):输入测试用例数量
for i in range(t):遍历每个测试用例
n = int(input()):输入物品的数量
li = list(map(int,input().split()):输入初始的物品价值列表
2.执行操作计算
ans = 0:初始化一个变量ans,用于存储价值之和
cnt = 0:初始化一个计数器cnt,用于统计操作次数
for i in range(n):遍历物品价值列表
if li[i] == 0:如果当前物品价值为0
li[i] += 1:将当前物品价值加一
cnt += 1:操作次数加一
ans += li[i]:更新价值之和
if ans == 0:如果价值之和为0
cnt += 1:操作次数加一
例题3:DNA序列修正
题目描述:
在生物学中,DNA序列的相似性常被用来研究物种间的亲缘关系。现在我们有两条DNA序列,每条序列由A,G,C,T四种字符,长度相同。但是我们现在记录的DNA序列存在错误,为了严格满足DNA序列的碱基互补配对即A -- T,C -- G,我们需要依据第一条DNA序列对第二条DNA序列进行以下操作:
1.选择第二条DNA序列的任意两个位置,交换他们的字符
2.选择第二条DNA序列的任意一个位置,将其替换为A,G,C,T中的任何一个
需要注意的是,每个位置上的碱基只能被操作一次!
你的任务是通过最小的操作次数,使第二条DNA序列和第一条DNA序列互补。并且已知两条DNA序列的长度为N。
输入格式:
第一行包含一个整数N,(1 <= N <= 10^3),表示DNA序列的长度。
接下来的两行,每行包含一个长度为n的字符串,表示两条DNA序列。
输出格式:
输出一个整数,表示让第二条DNA序列和第一条DNA序列互补的最少操作次数。
参考答案:
n = int(input())
x1 = {'A':'T','T':'A','C':'G','G':'C'}
a = list(input())
b = list(input())
ans = 0
for i in range(n):
if b[i] != x1[a[i]]:
for j in range(i + 1,n):
if x1[a[i]] == b[j] and x1[a[j]] == b[i]:
b[i],b[j] = b[j],b[i]
break
ans += 1
print(ans)
运行结果:
接下来是我的一些思路,本人观点而已。
这段代码解决了两条DNA序列互补配对的问题,通过最小的操作次数使得两条DNA序列互补。
1.输入处理
n = int(input()):输入DNA序列的长度
x1 = {'A':'T','T':'A','C':'G','G':'C'}:定义一个字典,记录碱基互补配对原则
a = list(input()):第一条DNA序列
b = list(input()):第二条DNA序列
2.计算操作次数
ans = 0:初始化一个变量ans,用来统计操作次数
for i in range(n):遍历两条DNA序列的每个位置
if b[i] != x1[a[i]]:如果第二条DNA序列不满足碱基互补配对原则
for j in range(i + 1,n):从当前位置遍历第二条DNA序列
if x1[a[i]] == b[j] and x1[a[j]] == b[i]:如果找到了满足交换条件的位置
b[i],b[j] = b[j],b[i] :交换即可
break:跳出循环
ans += 1:操作次数加一
3.输出结果
print(ans):输出最少的操作次数
这段代码的核心思想是通过遍历两条DNA序列的位置,如果当前位置不满足碱基互补配对原则,则从当前位置向后查找满足交换条件的条件,然后交换字符,增加操作次数。最终输出最小的操作次数,使得两条DNA序列互补。
例题4:无尽的石头
题目描述:
在一个古老的迷宫中,有一道无尽的通道。通道上每隔一定的距离就有一块神奇的石头,石头上刻着从1开始的连续整数,从1号石头开始,每块石头的编号都比前一块大1。
石头上的数字有特殊的意义。如果你站着编号为n的石头上,并向前走,你将会瞬间移动到编号为n + x的石头上,其中x为编号的各数位之和。
例如,你站在编号为16的石头上,由于1 + 6 = 7,则16 + 7 = 23,你将会瞬间移动到编号为23的石头上。
现在,会有多次询问,你需要对每个询问从1号石头出发,到达指定编号石头的最小步数。如果无法到达,则输出-1。
输入格式:
输入一个整数t(1 <= t <= 100),表示有t个询问。
接下来t行,每行一个整数n,1 <= n <= 10^6,表示目标石头的编号。
输出格式:
对于每个询问,输出一行,表示从1号石头到达目标石头的最少步数,如果无法到达,则输出-1。
参考答案:
stones = {}
def pre():
x = 1
cnt = 0
while x <= 1e6:
stones[x] = cnt
cnt += 1
x += sum(map(int,list(str(x))))
pre()
t = int(input())
for i in range(t):
x = int(input())
if x in stones:
print(stones[x])
else:
print(-1)
运行结果:
接下来是我做题的思路:
1.预处理函数
stones = {}:初始化一个字典stones,用于存储石头的编号和到达给石头的最小步数
x = 1:初始化起始石头的编号为1
cnt = 0:初始化步数为0
while x <= 1e6:循环条件,处理所有编号不超过1e6的石头
stones[x] = cnt:将当前石头编号和步数存储在字典中
cnt += 1:增加步数
x += sum(map(int,list(str(x)))):计算下一个石头的编号,即当前编号的各数位之和
2.预处理
pre():函数被调用,用于提前计算并存储所有石头的编号和到达该石头的最小步数
3.处理询问
t = int(input()):输入询问的次数
for i in range(t):循环处理每个询问
x = int(input()):输入目标石头的编号
if x in stones:如果目标石头的编号在预处理的字典中存在
print(stones[x]):输出到达目标石头的最小步数
else:如果目标石头的编号不在字典中
print(-1):输出无法到达的情况
这段代码通过预处理计算每个石头的编号和到达该石头所需要的最少步数,并在接受用户的询问时直接查找字典,从而高效地解决了问题。
例题5:计算函数值
题目描述:
在一个神秘的世界中,存在一个传说中的神秘花园,被认为拥有无限的知识。但要进入这个花园,你必须解决花园入口处的一道神秘难题。这个难题与一个特殊的数学函数有关,称为神秘函数。
神秘函数S(x)的定义如下:
当x 为0时,S(0)= 1
当x为偶数时,S(x) = S(x / 2)
当x为奇数时,S(x) = S(x - 1 ) + 1
你需要编写一个程序,计算给定正整数x,神秘函数S(x)的值。
只有当你正确解决了这道难题,才能获得通行证,进入神秘花园并探索其中的神秘宝藏。
输入格式:
输入包含一个正整数x(1 <= x <= 10^6),表示你要解决的神秘函数问题
输出格式:
输出一个整数,表示神秘函数S(x)的值,即你成功解决神秘难题后得到的答案。
参考答案:
def S(x):
if x == 0:
return 1
elif x % 2 == 0:
return S(x / 2)
else:
return S(x - 1) + 1
x = int(input())
print(S(x))
运行结果:
例题6:带分数
题目描述:
100可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为100 = 82 + 3546 / 197
注意特征,带分数中,数字1 - 9分别出现且只出现一次,但不包括0
类似这样的带分数,100有11种表示法
输入描述:
从标准输入读入一个整数N(N < 1000*1000)。
输出描述:
程序输出该数字用数码1 - 9不重复不遗漏地组成带分数表示的全部种数
注意:不要求输出每个表示,只统计有多少表示法!
参考答案:
import itertools
n = int(input())
ans = 0
for st in itertools.permutations('123456789'):
st = ' '.join(st)
for i in range(len(str(n))):
a = int(st[:i + 1])
if a >= n:
break
bl = (n - a) * int(st[-1]) % 10
if bl == 0:
continue
ind_b = st.index(str(bl))
if ind_b <= i or ind_b >= 8:
continue
b = int(st[i + 1:ind_b + 1])
c = int(st[ind_b + 1:])
if n == (a + b / c):
ans += 1
print(ans)
OK,这篇就这样了,下一篇继续!