携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
1.
Tom听说朋友新开了一个柠檬水摊,每一杯柠檬水的售价为 5 元。 顾客排队购买产品,(按账单 bills 支付的顺序)一次购买一杯。 每位顾客只买一杯柠檬水,然后向老板付 5 元、10 元或 20 元。老板必须给每个顾客正确找零,也就是说净交易是每位顾客向老板支付 5 元。 但是因为是第一次做生意,一开始老板手头没有任何零钱,这就导致可能无法给顾客找零,得到差评。Tom的朋友想请你编写程序,判断按照账单是否能正确找零。
输入格式:
给定一个账单bills,列表形式。
输出格式:
如果你能给每位顾客正确找零,返回 True ,否则返回 False 。
输入样例:
[5,5,5,10,20]输出样例:
True样例说明
前 3 位顾客那里,我们按顺序收取 3 张 5 元的钞票。 第 4 位顾客那里,我们收取一张 10 元的钞票,并返还 5 元。 第 5 位顾客那里,我们找还一张 10 元的钞票和一张 5 元的钞票。 由于所有客户都得到了正确的找零,所以我们输出 True。代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
分析🤔:一道很简单的题目,只需要判断列表里面的元素即可。但是需要注意将每一 种情况都考虑在内。
def change(bills):
if bills[0]!=5:
return False
else:
bills2 = bills[1:]
five_money=1
ten_money=0
for i in bills2:
if i == 5:
five_money += 1
elif i == 10:
five_money -= 1
ten_money += 1
else:
if ten_money >= 1:
ten_money -= 1
five_money -= 1
else:
five_money -= 3
if five_money < 0 or ten_money < 0:
return False
return True
if __name__ == '__main__':
bills=list(map(int,eval(input())))
canchange=change(bills)
if canchange==False:
print('False',end="")
else:
print("True",end="")
2.
Tom是个小菜菜,虽然有emoji大佬帮忙上强度,但是Tom觉得必须提高自己,来帮助emoji大佬给大家更好的训练,于是Tom去找kekao师傅"拜师学艺"。
恰巧碰到kekao师傅在串手链。哦,原来是kekao师傅觉得买的手链没有自己做的更有心意,于是他买了一堆珠子准备自己做一个,但他是一个重度选择困难症患者,于是Tom提议,至少保证手链一半以上的位置有珠子。但是Tom和kekao不知道有多少种串法,想请你帮忙计算一下。对于一个长度为n的绳子来说,每一个位置可以放上一个珠子,有珠子表示为1,没珠子表示为0。输入格式:
输入一个正整数n (1≤n≤18)
输出格式:
输出每一个串,每个串占一行 (从小到大输出)串的长度是n。
\最后一行输出串法的数量。输入样例:
在这里给出一组输入。例如:
3输出样例:
在这里给出相应的输出。例如:
011 101 110 111 amount = 4样例说明:
对于长度为3的串,所有串法是: 000 001 010 011 100 101 110 111 但是要保证每一个手链的珠子数量大于串长度的一半,于是得到上述答案。输入样例:
在这里给出一组输入。例如:
6输出样例:
在这里给出相应的输出。例如:
001111 010111 011011 011101 011110 011111 100111 101011 101101 101110 101111 110011 110101 110110 110111 111001 111010 111011 111100 111101 111110 111111 amount = 22代码长度限制 16 KB Python (python3)
时间限制 2000 ms
内存限制 64 MB
时间限制 1000 ms
内存限制 64 MB
分析🤔:通过题意我们可以知道对于长度为n的绳子,01串的串法数量是2^n。而我们需要将其排序组合,不难发现对于长度为n,数值最小的串是n个0,最大的是n个1,这与二进制非常相似。事实证明,对于长度为n的01串,如果我们将其看成二进制,那么它转化为十进制的数值范围是0 ~ 2^n -1。所以问题就转化为求0~ 2^n-1的二进制,并判断01串中0与1的数量即可。但是我们知道2^n存在指数爆炸,所以要考虑时间问题,此处我们采用按位与运算,而不是内置bin()函数,可以大幅降低时间。
n = int(input())
amo = 0
def f(r):
global amo
st = ""
while (r):
# print(r&1,end=" ")
st += str((r & 1))
r >>= 1
while (len(st) < n):
st += "0"
if st.count("1") > len(st)/2:
print(st[::-1])
amo += 1
temp = 2**n
for i in range(0,temp):
f(i)
print(f"amount = {amo}")
3.
将1……N的数字按照升序排列,在下一行按照降序排列。
1 2 3 ... ... N-1 N N N-1 N-2 ... ... 2 1kekao师傅问Alan:按照上述排列,对于给定的n,有多少个素数对?
Alan想请你帮忙编写程序,帮助求解一下。
输入格式:
在一行中给定一个整数N (1≤N≤10^4)
输出格式:
输出一个整数表示素数对的个数
输入样例:
在这里给出一组输入。例如:
3输出样例:
在这里给出相应的输出。例如:
1样例说明
1 2 3 3 2 1 素数对是: | 2 | | 2 |输入样例:
在这里给出一组输入。例如:
7输出样例:
在这里给出相应的输出。例如:
2代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
分析🤔: 一道简单题,只需要注意位置即可。 对于上一列的第i个,在下一列与其成对的存在是n+1-i。
def prime(num):
if num == 1:
return 0
elif num == 2:
return 1
7-5 不同进制的A+B
本题主要是熟悉各进制数字间的运算,可以将其都转化为我们熟悉的十进制运
算,再输出二进制结果。
7-6 Alan的小假期
由题意得,即求得1-n中与n互质的数的个数。但是这里不采用force方法,使用欧
拉函数和线性筛的优化。
欧拉函数和线性筛
else:
for i in range(2,int(num**0.5)+2):
if num%i == 0:
return 0
return 1
n = int(input())
res = 0
if n < 2:
res = 0
else:
for i in range(2,n+1):
if prime(i) and prime(n+1-i):
res += 1
print(res)
4.
我们将整数 x 的 权重 定义为按照下述规则将 x 变成 1 所需要的步数:
- 如果 x 是偶数,那么 x = x / 2
- 如果 x 是奇数,那么 x = 3 * x + 1 比方说,x=3 的权重为 7 。因为 3 需要 7 步变成 1 (3 --> 10 --> 5 --> 16 --> 8 --> 4 --> 2 --> 1)。
Alan现在给你三个整数 l, r 和 k 。你的任务是将区间 [l, r] 之间的整数按照它们的权重 升序排序 ,如果大于等于 2 个整数有 相同 的权重,那么按照数字自身的数值 升序排序 。
Alan想请你找出区间 [l, r] 之间的整数按权重排序后的第 k 个数。
注意,题目保证对于任意整数 x (l <= x <= r) ,它变成 1 所需要的步数是一个 32 位有符号整数。
输入格式:
第一行两个整数 l, r 。1≤ l ≤ r≤ 1000
第二行一个整数 k
输出格式:
输出一个整数,区间 [l, r] 之间的整数按权重排序后的第 k 个数。
输入样例:
12 15 2输出样例:
13样例说明:
12 的权重为 9(12 --> 6 --> 3 --> 10 --> 5 --> 16 --> 8 --> 4 --> 2 --> 1) 13 的权重为 9 14 的权重为 17 15 的权重为 17 区间内的数按权重排序以后的结果为 [12,13,14,15] 。 对于 k = 2 ,答案是第二个整数也就是 13 。 注意,12 和 13 有相同的权重,所以我们按照它们本身升序排序。14 和 15 同理。输入样例:
1 1 1输出样例
1输入样例:
1 1000 777输出样例:
570代码长度限制 16 KB
时间限制 100 ms
内存限制 64 MB
分析🤔:对于x的权重求值,我们可以采用递归的方式,构造如下递归式:
对于每一个数字,依据其权重排序,我们可以使用字典,以数字作为键key,权重作为值
value,进行排序。
在递归过程中我们可以发现,当我们求解 f(3) 的时候,会调用到 f(10),在求 f(20) 的
时候也会调用 f(10) ,同样的,如果单纯递归计算权重的话,会存在很多重复计算,我们可以
用记忆化的方式来加速这个过程,即「先查表,再计算」和「先记忆,再返回」。我们可以用一
个哈希映射作为这里的记忆化的「表」,这样保证每个元素的权值只被计算 1 次。在[1,1000]
中所有 x 求 f(x) 的值的过程中,只可能出现 2228 种 x,于是效率就会大大提高。代码如
下:
def getNum(l, r, k):
d_index = {1: 0}
def getF(x):
if x in d_index:
return d_index[x]
d_index[x] = (getF(x * 3 + 1) if x % 2 == 1 else getF(x // 2)) + 1
return d_index[x]
arr = list(range(l, r + 1))
arr.sort(key=lambda x: (getF(x), x))
return arr[k - 1]
if __name__ == "__main__":
l, r = map(int, input().split())
k = int(input())
print(getNum(l, r, k))
时间复杂度:平均情况下比较的次数为 nlogn