Python解题 - CSDN周赛第29期 - 争抢糖豆
创始人
2024-05-27 18:47:12
0

本期问哥是志在必得,这本算法书我已经觊觎许久,而之前两次因为种种原因未能如愿。因此,问哥这几天花了不少时间,把所有之前在每日一练做过的题目重新梳理了一遍。苦心人,天不负,感谢官方大大!


第一题:订班服

小A班级订班服了! 可是小A是个小糊涂鬼,整错了好多人的衣服的大小。 小A只能自己掏钱包来补钱了。 小A想知道自己至少需要买多少件衣服。

输入描述:第一行输入一个整数n。(1<=n<=100)表示衣服的数量。 以下n行输入n个尺码。表示订单中衣服的尺码。 接下来n行输入n个尺码。小A订的衣服尺码。 尺码表:M,S,L,XL,XLL,XLLL,XLLLL,XLLLLL。

输出描述:输出至少需要买多少件衣服。

示例:

示例
输入

2

XL
X
M
X

输出1

分析

简单题。需要 n 件衣服,买了 n 件衣服,所以只要把需要的 n 件衣服每种尺码的个数,减去已购买的衣服相应尺码的个数,如果大于0就说明该尺码还需要购买。所以最直接的办法就是用哈希表记录每种尺码的个数,然后再逐个检查。

Python已经提供了内置Counter类,可以自动生成字典,而且支持加减法,连逐个检查这一步都省去了:直接相减,剩下的数字加在一起就是答案。

参考代码

n = int(input().strip())
arr1 = [input().strip() for _ in range(n)]
arr2 = [input().strip() for _ in range(n)]
from collections import Counter
clothes = Counter(arr1) - Counter(arr2)
print(sum(clothes.values()))

第二题:争抢糖豆

抓糖豆,小Q与小K都喜欢吃糖豆。 但是糖豆分两种,超甜糖豆和普通糖豆。 现在有w个超甜糖豆和b个普通糖豆。 小Q和小K开始吃糖豆,他们决定谁先吃到超甜糖豆谁就获胜。 小K每次吃的时候会捏碎一颗糖豆。 小Q先吃,小Q想知道自己获胜的概率。 如果两个人都吃不到超甜糖豆小K获胜。

输入描述:输入两个整数w,b。(0<=w,b<=1000)

输出描述:答案保留9位小数。

示例:

示例
输入1 3
输出0.500000000

分析

也是以前考过的老题了。可以用递归或动态规划来做,但本题的状态转移不太容易一眼发现,所以可能不少人会觉得难。因为问到概率(胜率),所以本质上还是需要用数学来表达。

以动态规划为例(递归容易超时),我们用 dp[w][b] 表示当有 w 颗超甜糖豆,和 b 颗普通糖豆时自己的胜率。因为先吃到超甜糖豆就获胜了,所以自己要想获胜,只能分成两种情况:

  1. 先吃到超甜糖豆,概率是 \frac{w}{w+b}  ,此情况下直接获胜;
  2. 先吃到普通糖豆,但是对手也吃到普通糖豆,所以游戏继续,自己还有获胜的可能。(这里有一个特判的情况:如果只有一颗普通糖豆,而自己先吃到普通糖豆的话,无论如何也是输,后面自然就不用算了。)因此,自己和对手都吃到普通糖豆的概率是 \frac{b}{w+b} * \frac{b-1}{w+b-1}  。(如果一时看不懂可以多琢磨几遍,乘号左边是自己吃到普通糖豆的概率,右边是自己吃完后对方也吃到普通糖豆的概率,看懂了再继续。)

如果没有“捏碎糖豆”的操作,分析到这就结束了,状态转移就是把这两种情况的胜率加在一起,方程如下:

dp[w][b]=\frac{w}{w+b}+\frac{b}{w+b}*\frac{b-1}{w+b-1}*dp[w][b-2]

(因为自己和对手总共吃了两颗普通糖豆,所以上面第二种情况的概率还要乘以 dp[w][b-2] 才是胜率。)

如果上面的内容理解了,我们再来分析“捏碎糖豆”的情况。

捏碎糖豆也有两种情况:

  1. 捏碎了普通糖豆。影响不大,但是上面的第二种状态要接着乘上捏碎普通糖豆的概率,再乘以 dp[w][b-3] 。合在一起的胜率就是 \frac{b}{w+b}*\frac{b-1}{w+b-1}*\frac{b-2}{w+b-2}*dp[w][b-3] 。
  2. 捏碎了超甜糖豆。则二人虽不分胜负,理论上自己还存在胜利的可能(如果还剩下超甜糖豆的话),但是同样地,状态转移方程变了,胜率变成了:\frac{b}{w+b}*\frac{b-1}{w+b-1}*\frac{w}{w+b-2}*dp[w-1][b-2] 。

这两种捏碎糖豆的情况属于同一决策层级,可以加在一起。于是把捏碎糖豆考虑进来,得到最终的状态转移方程如下:

dp[w][b]=\frac{w}{w+b}+\frac{b}{w+b}*\frac{b-1}{w+b-1}*(\frac{b-2}{w+b-2}*dp[w][b-3]+\frac{w}{w+b-2}*dp[w-1][b-2])

此外,如之前所述,还要考虑几个特判的情况:

  1. 没有超甜糖豆,胜率为0,不用计算。
  2. 没有普通糖豆,胜率100%。
  3. 只有一颗普通糖豆,胜率为\frac{w}{w+b} ,因为如果自己先吃到普通糖豆,必输。

很显然,上面第二、三可以合并,而第一条可以在初始化的时候把 dp[0][j],0\leq j\leq b 的时候设置为0。代码如下:

参考代码

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(f"{dp[w][b]:.9f}")

输出结果的时候要注意,题目要求必须保留9位小数,空位用0补全,所以要设置占位符。


第三题:走楼梯

现在有一截楼梯,根据你的腿长,你一次能走 1 级或 2 级楼梯,已知你要走 n 级楼梯才能走到你的目的楼层,请实现一个方法,计算你走到目的楼层的方案数。

输入描述:输入整数n。(1<=n<=50)

输出描述:输出方案数。

示例:

示例
输入5
输出

8

分析

很明显,答案是斐波那契数列。因为一次只能走 1 级或 2 级楼梯,所以第 n 级阶梯可以由 n-1 级阶梯走过来,也可以由 n-2 级阶梯走过来。如果用函数 f(n) 表示走上第 n 级阶梯的方案数,可得

f(n) = f(n-1)+f(n-2)

因为本题 n 范围较小(1<=n<=50),所以使用递归来做应该也没问题。不过更常用的做法是递推,也算是斐波那契的模板题了。

参考代码

n = int(input().strip())
a = b = 1
for _ in range(n):a, b = b, a+b
print(a)

第四题:打家劫舍

一个小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

输入描述:输入一个正整数n代表房屋的数量(n≤100),接着输入n个非负整数代表每间房屋的现金数量

输出描述:小偷能偷取的最大金额。

示例:

示例
输入4
1 2 3 1
输出4

分析

力扣原题,经典的打家劫舍系列,但凡刷过点题的相信都做过。而且这里选取的是该系列最简单的一道,动态规划入门题,相关题解太多了,这里问哥只简单说两句吧。

因为相邻的房屋不能同时被盗,所以小偷在当前房屋只有两种选择:不偷当前房屋——继承上个房屋可偷取的的最大金额,偷当前房屋——上上个房屋可偷取的最大金额(因为上个房屋不能偷)加上当前房屋的金额,而当前房屋可偷取的最大金额就等于这两种选择中较大的金额。

如果用 f(i) 代表当前房屋可偷取的最大金额,H_{i} 表示当前房屋的金额,可用公式表示如下:

f(i)=max({f(i-1),f(i-2)+H_{i}})

类似斐波那契数列,可以看出 f(i) 仅由 f(i-1) 和 f(i-2) 得到(H_{i} 是给定数组),所以可以使用滚动数组优化空间,换句话说就是只需要额外两个变量循环保存 f(i-1) 和 f(i-2) 的值即可。

参考代码

n = int(input().strip())
arr = [int(item) for item in input().strip().split()]
a = b = 0
for i in arr:a, b = b, max(b, a+i)
print(b)

相关内容

热门资讯

立夏的谚语 关于立夏的谚语(精选60句)  在学习、工作、生活中,许多人都接触过一些比较经典的谚语吧,谚语是民众...
我在暑假期间学习写的作文 我在暑假期间学习写的作文我在暑假期间学习写的作文 (中国大学网 unjs.com)  今年暑假,我上...
中秋节花灯谜语 中秋节花灯谜语  中秋月圆夜在公共场所挂着许多灯笼,人们都聚集在一起,猜灯笼身上写的谜语,小编今天为...
砌墙的砖头的歇后语   以下是小编给大家整理的砌墙的砖头的歇后语,欢迎大家查看。  砌墙的砖头——后来居上  关于砖头的...
学习知识方面的谚语 关于学习知识方面的谚语(精选110句)  在日常学习、工作抑或是生活中,大家或多或少都接触过一些经典...
古代对联经典 古代对联经典  在日常的学习、工作、生活中,大家都对那些朗朗上口的对联很是熟悉吧,对联的格式精巧玲珑...
王维《九月九日忆山东兄弟》译... 王维《九月九日忆山东兄弟》译文及赏析  王维参禅悟理,精通诗书音画,以诗名盛于开元、天宝间,尤长五言...
摘抄优美排比句 摘抄优美排比句  排比句,是修辞手法之一,指使用排比修辞方法,把三个或以上意义相关或相近、结构相同或...
寒假周记 寒假周记范文合集6篇  时间是箭,去来迅疾,转眼一周又结束了,一周的时间,想必你学习了很多新技巧,此...
2017年小年祝福语短【最新...   农历十二月二十三日或二十四日,民间称为过小年,是祭祀灶君的节日。小编收集了2017年小年祝福语短...
数字对联 数字对联大全  随着社会不断地进步,大家都有令自己印象深刻的.对联吧,对联作为一种习俗,是汉族传统文...
作文 点燃感恩的火种 作文 点燃感恩的火种点燃感恩的火种    礼县王坝中心小学五年级 张亚军    指导教师:赵旺平  ...
古代文学常识 有关古代文学常识汇总  文学常识广义指涵盖文化的各种问题。包括作家,年代,作品,文学中的地理,历史各...
语文是什么排比句 语文是什么排比句  语文是神态悠闲的白云,让人浮想联翩;下面是小编为你带来的语文是什么排比句相关内容...
虎年春节经典春联 关于2022年虎年春节经典春联  在学习、工作、生活中,大家都经常接触到春联吧,春联的颜色又与当地民...
林升《题临安邸》的写作背景 林升《题临安邸》的写作背景  《题临安邸》是宋代诗人林升创作的一首七绝。下面为大家带来了林升《题临安...
迎新春的对联 关于迎新春的对联(精选100句)  在日常学习、工作或生活中,大家或多或少都接触过一些对联吧,对联形...
形容音乐的比喻句 形容音乐的比喻句  音乐是智慧的创造,也是陶冶人情操的一种重要方式,那么该怎么对音乐进行比喻呢?以下...
冬至的谚语 关于冬至的谚语大全  在日常生活或是工作学习中,大家都听说过或者使用过一些比较经典的谚语吧,谚语一般...
墓碑对联 春节对联推荐度:虎年对联推荐度:新春对联推荐度:新居入伙对联推荐度:春节虎年对联推荐度:相关推荐