CSDN编程题-每日一练(2023-08-17)
- 一、题目名称:计算公式
- 二、题目名称:计算逆波兰表达式的结果
- 三、题目名称:争抢糖豆
一、题目名称:计算公式
时间限制:1000ms内存限制:256M
题目描述:
给定整数n。 计算公式: n i-1
∑ ∑ [gcd(i + j, i - j) = 1]
i=1 j=1
输入描述:
输入整数n。(1<=n<=1e6)
输出描述:
输出答案
🚩 示例:
✔️ 示例1:
输入
233
输出
11065
🔔 解题思路:
首先,我们需要明确计算公式的含义。公式中的i和j都是从1开始的,并且满足gcd(i + j, i - j) = 1。我们需要计算一个双重求和的公式。
代码如下:
import math
def calc(n):
result = 0
for i in range(1, n+1):
for k in range(1, (i//2) + 1):
if math.gcd(i+k, i-k) == 1:
result += 2
return result
n = int(input())
print(calc(n))
二、题目名称:计算逆波兰表达式的结果
时间限制:1000ms内存限制:256M
题目描述:
逆波兰记法中,操作符置于操作数的后面。例如表达“三加四”时,写作“3 4 +”,而不是“3 + 4”。如果有多个操作符,操作符置于第二个操作数的后面,所以常规中缀记法的“3 - 4 + 5”在逆波兰记法中写作“3 4 - 5 +”:先3减去4,再加上5。使用逆波兰记法的一个好处是不需要使用括号。例如中缀记法中“3 - 4 * 5”与“(3 - 4)*5”不相同,但后缀记法中前者写做“3 4 5 * -”,无歧义地表示“3 (4 5 *) -”;后者写做“3 4 - 5 *”。(测试用例仅做参考,我们会根据代码质量进行评分)
输入描述:
第一行输入一个整数 n,表示包含元素数量.(1<=n<=1000) 第二行输入n个元素。
输出描述:
输出计算后的结果。
🚩示例:
✔️示例1
输入
2
1 + 3 *
输出
9
🔔 解题思路:
使用一个栈来辅助计算,遍历输入的表达式元素。如果遇到操作数,则将其入栈;如果遇到操作符,则从栈中取出两个操作数进行计算,并将结果再次入栈。最后,栈中剩下的唯一元素即为计算结果。
代码如下:
def calc(s):
stack = []
for token in s:
if token.isdigit():
stack.append(int(token))
elif token == '+':
num2 = stack.pop()
num1 = stack.pop()
stack.append(num1 + num2)
elif token == '-':
num2 = stack.pop()
num1 = stack.pop()
stack.append(num1 - num2)
elif token == '*':
num2 = stack.pop()
num1 = stack.pop()
stack.append(num1 * num2)
elif token == '/':
num2 = stack.pop()
num1 = stack.pop()
if num1 % num2 == 0: # 如果能整除,则结果是整数
stack.append(int(num1 // num2))
else:
stack.append(int(num1 / num2))
return stack[0]
s= input().split()
result = calc(s)
print(result)
参考其他解法:
s = input().split()
z = []
for i in s:
z.append(str(int(eval(z.pop() + i + z.pop()))) if i in '+-*/' else i)
print(z[0])
三、题目名称:争抢糖豆
时间限制:1000ms内存限制:256M
题目描述:
抓糖豆,小Q与小K都喜欢吃糖豆。 但是糖豆分两种,超甜糖豆和普通糖豆。 现在有w个超甜糖豆和b个普通糖豆。 小Q和小K开始吃糖豆,他们决定谁先吃到超甜糖豆谁就获胜。 小K每次吃的时候会捏碎一颗糖豆。 小Q先吃,小Q想知道自己获胜的概率。 如果两个人都吃不到超甜糖豆小K获胜。
输入描述:
输入两个整数w,b。(0<=w,b<=1000)
输出描述:
答案保留9位小数。
🚩示例:
✔️示例1
输入
3 3 2
输出
2
🔔 解题思路:
我们可以使用动态规划来解决这个问题。设 dp[w][b] 表示在剩下 w 个超甜糖豆和 b 个普通糖豆的情况下,小 Q 获胜的概率。
根据题目描述,小 Q 先开始吃糖豆,而小 K 每次吃的时候会捏碎一颗糖豆。因此,小 Q 只能通过吃掉一个普通糖豆来改变局面。当小 Q 吃掉一个普通糖豆后,剩下的糖豆数量变为了 w 和 b-1。
可以得到状态转移方程:
dp[w][b] = w / (w + b) + (b / (w + b)) * (1 - dp[w][b-1])边界条件为:当没有超甜糖豆时,小 Q 不可能获胜,所以 dp[0][b] = 0;当没有普通糖豆时,小 Q 必定获胜,所以 dp[w][0] = 1。
最终答案为 dp[w][b],即在初始状态下,小 Q 获胜的概率。
代码如下:
def calc(w, b):
if w == 0:
return 0
if b == 0:
return 1
dp = [[0.0] * (b + 1) for _ in range(w + 1)]
dp[0][b] = 0
dp[w][0] = 1
for i in range(1, w + 1):
for j in range(1, b + 1):
dp[i][j] = i / (i + j) + (j / (i + j)) * (1 - dp[i][j-1])
return dp[w][b]
w, b = map(int, input().split())
result = calc(w, b)
print('{:.9f}'.format(result))
参考其他解法:
w, b = map(int, input().split())
dp = [[0]*(b+1) for _ in range(w+1)]
for i in range(1, w+1):
for j in range(b+1):
if j <= 1:
dp[i][j] = i / (i + j)
else:
dp[i][j] = i / (i + j) + j / (i + j) * (j - 1) / (i + j - 1) * ((j - 2) / (i + j - 2) * dp[i][j - 3] + i / (i + j - 2) * dp[i - 1][j - 2])
print("{:.9f}".format(dp[w][b]))