目录
题解代码
欢迎关注 【牛客周赛】系列,持续更新中……
A 小红的字符串
题意描述
题解代码
# 读取输入并计算不同字符的数量
unique_chars = len(set(input()))
# 输出结果,长度为3的字符串的特殊性质允许这样快速计算。
print(unique_chars - 1)
B 小红的序列乘积
题意描述
题解代码
# 初始化结果为0
result = 0
# 直接读取一行输入
input() # 读取但不使用,因为只关心第二行的数
# 初始化一个变量用于连乘的结果,初始值为1
product = 1
# 遍历输入的每一个数字(以空格分隔),并将其转换为整数
for number in map(int, input().split()):
# 更新连乘的结果,并只保留个位数
product = product * number % 10
# 如果连乘结果的个位数为6,增加结果计数
if product == 6:
result += 1
# 输出最终的计数结果
print(result)
C 小红的数组重排
题意描述
题解代码
# 读取输入值的数量
length = int(input())
# 读取整数序列并转换为整数列表
numbers = list(map(int, input().split()))
# 对数字列表进行排序
numbers.sort()
# 检查排序后的序列中任意三个连续元素是否满足给定条件
for i in range(length - 2):
if numbers[i] * numbers[i + 1] >= numbers[i + 1] * numbers[i + 2]:
print("NO")
break
else:
# 如果循环正常结束,没有中途break,则输出YES和排序后的列表
print("YES")
print(" ".join(map(str, numbers)))
D 虫洞操纵者
题意描述
题解代码
E 小红的序列乘积2.0
题意描述
题解代码
MOD = 1_000_000_007
def read_input() -> (int, list):
"""读取输入并返回整数个数和整数列表"""
num_count = int(input())
numbers = list(map(int, input().split()))
return num_count, numbers
def copy_list(original_list: list) -> list:
"""复制列表"""
return original_list[:]
def compute_dynamic_programming(num_count: int, numbers: list) -> list:
"""计算动态规划表"""
dp_table = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
for number in numbers:
number %= 10
last_dp = dp_table[-1]
next_dp = copy_list(last_dp)
for digit in range(10):
next_dp[(number * digit) % 10] += last_dp[digit]
dp_table.append(next_dp)
return dp_table
def compute_final_answer(num_count: int, dp_table: list) -> int:
"""根据DP表计算最终答案"""
answer = 0
for i in range(1, len(dp_table)):
answer += (dp_table[i][6] - dp_table[i - 1][6]) * pow(2, num_count - i, MOD)
answer %= MOD
return answer
def main() -> None:
"""主函数,用于执行程序逻辑"""
num_count, numbers = read_input()
dp_table = compute_dynamic_programming(num_count, numbers)
final_answer = compute_final_answer(num_count, dp_table)
print(final_answer)
if __name__ == '__main__':
main()
F 灯下定影
题意描述
题解代码
# 输入圆心坐标(x, y)和半径r
x, y, r = map(float, input().split())
def cald(a, b, c, d):
"""计算圆心到直线的垂直距离"""
if a == c:
# 当直线垂直于x轴时
return abs(x - a)
else:
# 一般情况下的点到直线距离公式
res = (b - d) * x + (c - a) * y + a * d - b * c
return abs(res) / ((b - d) ** 2 + (a - c) ** 2) ** 0.5
def judge(a, b, c, d):
"""判断线段是否在圆心可见的方向上"""
return (c - a) * (x - a) + (d - b) * (y - b) >= 0
# 读入线段数量n和时间增量plus
n, plus = map(int, input().split())
tmp = []
for ii in range(n):
a, b, c, d, e = map(float, input().split())
md = cald(a, b, c, d) # 圆心到直线的最短距离
R = ((x - a) ** 2 + (y - b) ** 2) ** 0.5 # 圆心到线段起点的距离
if md > r or not judge(a, b, c, d):
# 如果最短距离大于半径或者线段不在可见方向,跳过
continue
x2 = (r ** 2 - md ** 2) ** 0.5 # 圆与直线的交点到垂足的距离
x1 = (R ** 2 - md ** 2) ** 0.5 # 圆心到垂足的距离
t1 = (x1 - x2) / e # 最近交点时间
t2 = (x1 + x2) / e + plus # 最远交点时间
tmp.append([t1, t2])
# 对时间区间进行排序
tmp.sort(key=lambda x: x[0])
# 合并时间区间并计算总时间
if tmp:
ans = tmp[0][1] - tmp[0][0]
x = tmp[0][1]
for i in range(1, len(tmp)):
if tmp[i][0] > x:
ans += tmp[i][1] - tmp[i][0]
x = tmp[i][1]
elif tmp[i][1] > x:
ans += tmp[i][1] - x
x = tmp[i][1]
print(ans) # 打印总覆盖时间
else:
print(0) # 如果没有有效区间,输出0