比赛日期是七夕,题目如下
赛题去蓝桥杯官网备赛专区的算法双周赛可以找到https://www.lanqiao.cn/oj-contest/
1. 喜鹊罢工【算法赛】
问题描述
七夕节到了,牛郎织女一年一度的浪漫相会也即将到来。然而,天庭新近实施了一项不合理的政策——“加班不给加班费”,这导致喜鹊们纷纷抗议并罢工,拒绝参与搭建连接银河两岸的鹊桥。
面对这样的困境,织女决定采取行动,她打算用自己的巧手编织出美丽的彩虹丝巾来搭建一座天桥,以确保与牛郎的相会能够如期进行。
已知每条彩虹丝巾的长度都是精确的 7 米,而银河的宽度则是 365 米。在织女精湛的编织技艺下,每条丝巾与下一条丝巾的连接部分可以巧妙地融合,几乎不产生任何长度上的损失。现在,请你计算,织女至少需要编织多少条彩虹丝巾,才能成功跨越银河,与牛郎团聚。
输入格式
本问题不需要任何外部输入。
输出格式
请输出一个整数,代表织女为了搭建足够跨越银河的天桥,至少需要编织的彩虹丝巾的数量。
签到题
print(53)
2.牛郎取名【算法赛】
问题描述
什么?牛郎和织女竟然有孩子了!是的没错,在经过了每年一度的鹊桥相会后,他们的爱情终于开花结果。
为了给孩子取一个好听的名字,牛郎翻遍了天上的典籍,最终决定从织女精心准备的字符锦囊中按照特定的顺序选取所有字符来命名。
这个锦囊呀,一共包含了 n 个小写字符,牛郎苦思冥想后,确定了选取的顺序,并计划从织女的字符锦囊中分别取出,按顺序组成新的名字。
例如,锦囊里的字符是 abcd,牛郎选择了第 3,1,2,4 个字符,那么孩子的名字就是 cabd。
现在,牛郎将选取规则 p 告诉你,请你帮他算出最终会组成什么样的名字吧!
输入格式
第一行输入一个正整数 n(1≤n≤10**5),表示字符宝囊中字符的个数。
第二行输入一个长度为 n、仅包含小写字母的字符串 s ,表示字符宝囊中的字符。第三行输入 n 个整数 p1,p2,…,pn(1≤pi≤n,pi互不相同) ,表示选取字符的顺序。
输出格式
输出一行一个字符串,表示最终组成的名字。
样例输入
5
abcde
5 4 3 2 1
样例输出
edcba
代码(AC)
n = int(input())
arr = input()
brr = list(map(int,input().split()))
k = ''
for i in range(n):
k += arr[brr[i]-1]
print(k)
3. 织女的考验【算法赛】
问题描述
七夕节即将到来,七夕城热闹非凡,牛郎想邀约美丽的织女一同前往七夕城漫步。
织女并不想轻易地接受牛郎的邀约,于是向他提出了一个有趣的字符串问题:给定两个长度相等的小写字符串 S 和 T,牛郎需要判断是否可以从 S 和 T 中各删除一个字符,使得删除后的 S 经过重新排列后等于 T。若可以则输出 YES,否则输出 NO。
织女表示,如果牛郎能够回答正确,她就会同意牛郎的邀约。
但是,牛郎不太擅长处理字符串问题,为了抱得美人归,他需要你的帮助来解决这个问题。
输入格式
第一行输入一个整数 t,表示询问的数量。
接下来 t 行,每行输入两个小写字符串
S,T(1≤∣S∣,∣T∣≤10** 3 ) 表示一次询问。
数据保证
∑
i
=
1
T
∣
S
∣
\sum_{i=1}^{T} |S|
i=1∑T∣S∣
不超过 10 **6。
输出格式
输出 t 行,每行一个整数表示答案,
输入样例
3
aba aac
abc ade
c d
输出样例
YES
NO
YES
代码(暴力求解超时)
n = int(input())
arr = [list(map(str,input().split())) for _ in range(n)]
k = 0
for i in range(n):
if len(arr[i][0]) == 1:
print("YES")
continue
for j in range(len(arr[i][0])):
for z in range(len(arr[i][0])):
if arr[i][0][0:j] + arr[i][0][j + 1:len(arr[i][0])] == arr[i][1][0:z] + arr[i][1][z+1:len(arr[i][0])]:
k += 1
if k > 0:
print("YES")
k = 0
elif k == 0:
print("NO")
continue
**这里使用python的collections中的Counter,可以很好解决。
解题思路:
计算一下字符出现频次,然后对两个计算频次的结果的values,进行互相相减, 求和如果为0或者为2,即输出YES,否则输出NO
python的标准库中collections中的Counter相关简单使用,可以参考我的这篇文章蓝桥Python组标准库collections(1)
代码(AC)
from collections import Counter
n = int(input())
arr = [list(map(str,input().split())) for _ in range(n)]
for i in range(n):
k = (Counter(arr[i][0]) - Counter(arr[i][1])).values()
f = (Counter(arr[i][1]) - Counter(arr[i][0])).values()
if sum(k)+sum(f) == 0 or sum(k)+sum(f) == 2:
print("YES")
else:
print("NO")
Python 代码简洁在很多情况下也更高效,所以Python标准库的学习很重要(多刷题)。
4.仙男仙女【算法赛】
问题描述
七夕佳节,银河之上,鹊桥横跨,牛郎织女相会。
今年的鹊桥格外热闹,因为不仅织女翘首以盼,更有
n 位美丽的单身仙女也来到了这里,希望能邂逅属于自己的幸福。
为了方便区分,每位仙女都被分配了一个唯一的编号,分别为
1,2,…,n。由于仙女数量众多,鹊桥上显得拥挤不堪。我们可以把鹊桥看作是一条笔直的天河,仙女 i 位于天河上的坐标 p i 处。有些心急的仙女可能会挤在同一个坐标上,期盼着早点遇到心仪的对象。
为了维持秩序,同时也为了给仙女们创造一个良好的相亲环境,鹊桥的管理者月老决定制定一个规则:每位仙女都需要保持一定的安全距离。具体来说,对于仙女 i,月老会根据她的魅力值设定一个安全距离 a i 。只有当仙女 i周围 a i的距离(即 [pi−ai,pi+ai])内没有其他仙女时,她才能安心地与前来搭讪的仙男交谈,完成脱单。
然而,月老最近忙着为人间牵线搭桥,实在无暇顾及仙界的单身情况。因此,他找到了你,一个擅长算法的凡间少年,希望你能帮他算一下,今年七夕佳节,最终会有多少位仙女能够成功脱单?
输入格式
第一行包含一个整数 n(1≤n≤10** 5 ),表示仙女的数量。
第二行包含 n 个整数 p 1,p 2 ,…,p n(1≤pi≤10** 9),表示每位仙女在鹊桥上的坐标。
第三行包含 n 个整数 a1,a 2 ,…,a n(1≤ai≤10** 9),表示每位仙女的安全距离。
输出格式
输出一个整数,表示能够成功脱单的仙女数量。
样例输入
5
1 5 6 7 10
2 2 2 2 2
样例输出
2
样例说明
能够成功脱单的有编号为 1、编号为 5 的仙女。
解题思路
先排序
后遍历
代码(AC)
n = int(input())
arr = [list(map(int,input().split())) for _ in range(2)]
b = []
count = 0
for i in range(n):
b.append([arr[0][i],arr[1][i]])
b = sorted(b, key=lambda x:x[0])
if n >= 2:
if b[0][0] + b[0][1] < b[1][0]:
count += 1
if b[n-1][0] - b[n-1][1] > b[n-2][0]:
count += 1
for i in range(1,n-1):
if b[i][0] + b[i][1] < b[i+1][0] and b[i][0] - b[i][1] > b[i-1][0]:
count += 1
print(count)
5.牛郎的微信群【算法赛】
问题描述
在现代社会,随着通讯技术的高速发展,牛郎和织女不再依赖每年七夕才能相见,他们可以通过微信每天保持联系。
玩转微信的牛郎还建立了一个微信群,群里成员都是帮助过他们的喜鹊。
现在已知这个微信群里有 n 个成员,分别用 1,2,…,n 来标记。成员之间共有n−1 对朋友关系,这些关系形成了一棵树结构。
为了更好地组织交流,牛郎想请你帮他计算出每个成员的“朋友的朋友”数量。具体来说,对于每个成员 i=1,2,…,n,请你计算与该成员的距离为 2 的其他成员的数量(“距离”是指在树中两个成员之间直接相连的边的数量)。
输入格式
第一行包含一个整数 (2≤n≤2×10 **5),表示微信群成员的数量。
接下来 n−1 行,每行包含两个整数 u 和 v(1≤u,v≤n,u≠v),表示成员 u 和成员
v 之间存在朋友关系。
输出格式
输出一行,包含
n 个整数。第 i 个整数表示成员 i 的“朋友的朋友”的数量。
样例输入
5
1 2
1 3
1 4
2 5
样例输出
1 2 2 2 1
解题思路
邻接表来表示树结构,然后计算每个节点的“朋友的朋友”数量
代码(AC)
n = int(input())
arr = [[] for _ in range(n+1)]
for i in range(n-1):
p,q = map(int,input().split())
arr[p].append(q)
arr[q].append(p)
brr = [0]*(n+1)
for i in range(1,n+1):
for j in arr[i]:
brr[i] += (len(arr[j]) - 1)
for i in range(1,n+1):
print(brr[i],end=' ')
6.久别重逢【算法赛】
问题描述
每年的七月初七,本是牛郎织女鹊桥相会的甜蜜时刻。但在今年,状况突发,这对分别已久的恋人重逢时竟产生了一丝陌生,致使双方的亲密度降为 0。
为了重新点燃昔日的爱火,牛郎织女决定通过一次次的约会来提升亲密度。不过天庭有严格的规定,他们的亲密度不可超过 n。一旦超过 n,爱情之火就会因燃烧得过旺而触怒天条(天庭的戒律森严,对于爱情的尺度把控极为谨慎)。
牛郎深知每一次约会的机会都来之不易,他希望每次约会过后,亲密度能够至少能提升 k,毕竟他们相聚的时光是那样的短促,小幅度的增长实在难以满足他对爱情的热切渴望。他望着织女那熟悉又陌生的脸庞,心中暗暗发誓,一定要让这份感情恢复如初,甚至更加深厚。而织女又何尝不想与牛郎重归于好,她那美丽的眼眸中闪烁着坚定的光芒,愿意与牛郎一同努力,跨越这道因生疏而产生的情感鸿沟。
现在,请你计算出“在每次约会亲密度至少提升 k 且亲密度总和不超过 n 的前提下,牛郎和织女的亲密度可以有多少种不同的变化过程?由于答案可能很大,请将结果对10** 9+7 取余。
输入格式
输入仅一行,包含两个整数 n(1≤n≤10** 5 ),k(1≤k≤n),分别表示亲密度上限和每次约会后亲密度至少提升的幅度。
输出格式
输出一个整数,表示在每次约会亲密度至少提升 k 且亲密度总和不超过 n 的前提下,牛郎和织女亲密度变化过程的不同种类数对 10 ** 9+7 取余的结果。
样例输入
5 2
样例输出
8
样例说明
仅约会 0 次:
亲密度:0。
仅约会 1 次:
亲密度:0→2。
亲密度:0→3。
亲密度:0→4。
亲密度:0→5。
约会 2 次:
亲密度:0→2→4。
亲密度:0→2→5。
亲密度:0→3→5。
解题思路
动态规划问题,确定状态转移方程:
由题可知,因为每次约会亲密度需要至少提升 k,所以到达亲密度为n的种类数,与到达(n-k)的种类数相等。 -------推导1
所以可以完成如下推导:解释: f(x) 代表亲密度上限 x 的 变化过程的不同种类数
- 题意:f(n) = f(n)+f(n-1)+…+f(1)+f(0) -------------------公式1
- 由推导1:f(n)=f(n-k) -----------------------------公式2
- 当 x = n-k时, f(n-k) = f(n-k) + f(n-k-1)+…+f(1)+f(0) 结合公式2,可得
f(n) = f(n-k) + f(n-k-1)+…+f(1)+f(0) --------------------------------------公式3
f(n-1) = f(n-1-k) + f(n-k-2) + … f(1)+f(0) -----------------公式4
公式3 减 公式4 f(n) - f(n-1) = f(n-k) 即 f(n) = f(n-k) + f(n-1)
下面是代码实现
代码(AC)
n, k = map(int,input().split())
arr = [0]*(n+1)
arr[0] = 1
for i in range(n+1):
if i >= k:
arr[i] = arr[i-k] + arr[i-1]
mod = 10**9 + 7
print(sum(arr) % mod)