试题A:2023
![]()
题解
a='2023'
cnt,i,k=0,0,0
for j in range(12345678, 98765433):
while i<len(a):
while k < 8:
if a[i]==str(j)[k]:
cnt+=1
i+=1
k+=1
k+=1
print(98765433-12345678-cnt)
正确题解
- 语法:str.find(str, beg=0, end=len(string))
def find_i(i):#传入字符串
find_1 = i.find('2')#先找2,返回的是第一个2的下标
if find_1 == -1:#如果找不到,返回0
return 0
find_2 = i.find('0', find_1 + 1)#第二个找0,从第一个2开始往后找,返回第一个0的下标
if find_2 == -1:
return 0
find_3 = i.find('2', find_2 + 1)#第三个找2,从0开始往后找,返回0后的第一个2的下标
if find_3 == -1:
return 0
find_4 = i.find('3', find_3 + 1)#第四个找3,从上一个2开始往后找,返回2后的第一个3的下标
if find_4 == -1:
return 0
return 1#找到了返回1
ans = 0#计数
for i in range(12345678, 98765432 + 1):
if find_i(str(i)) == 0:#如果没找到含2023的计数加1
ans += 1
print(ans)
试题B:硬币兑换
试题C:松散子序列
![]()
- 问题转换:松散子序列的定义为索引之差大于2,相当于相邻两个元素不能同时取,直接破: 打家劫舍问题
- 打家劫舍问题,只需要处理一下字符串数组成int整数就可以直接带入模板
题解:动态规划
s=input()
nums=[]
for i in range(len(s)):
nums.append(ord(s[i]) - ord('a') + 1)
n = len(nums)
if n == 0:
ptint(0)
if n == 1:
print(nums[0])
# 初始化动态规划数组
dp = [0] * n
# base case
dp[0] = nums[0]#第1间
dp[1] = max(nums[0], nums[1])#第2间
# 状态转移
for i in range(2, n):#从第三间开始
dp[i] = max(dp[i-1], dp[i-2] + nums[i])#当前这间抢不抢,取决于前一家和前前家哪家抢得到的钱多
print(dp[n-1])#一直到最后一间
试题D:管道
![]()
![]()
题解:二分+区间合并
n, L = tuple(map(int, input().split())) # 会打开的阀门数 管道长度
tick = dict(tuple(map(int, input().split())) for _ in range(n)) # 管道编号 到 打开时刻的映射
def check(t: int) -> bool: # 判断t时刻是否能使得:管道中每一段中间的传感器都检测到有水流
intervals = sorted([[max(l - (t - s), 1), min(l + (t - s), L)] for l, s in tick.items() if t >= s]) # 每个阀门在t时刻能覆盖的区间集合
interval = intervals[0] # 阀门整体能覆盖的区间
for s, e in intervals[1:]: # 区间合并
if interval[1] < s - 1: # 没有覆盖完全
return False
interval[1] = max(interval[1], e) # 延伸右端点
return interval == [1, L] # 判断是否能覆盖完整个管道
left, right = 1, 10 ** 10 # 答案的取值范围[1, 10 ^ 10)
while left <= right: # 二分答案
mid = (left + right) >> 1
if check(mid): right = mid - 1
else: left = mid + 1
print(left)
试题E:保险箱