0
点赞
收藏
分享

微信扫一扫

第十一届蓝桥杯省赛第一场C++A/B组真题(节选)


文章目录

  • ​​一、整除序列(模拟)​​
  • ​​二、解码(字符串)​​
  • ​​三、走方格(简单DP)​​
  • ​​四、超级胶水(模拟)​​
  • ​​五、整数拼接(枚举+哈希表)​​

一、整除序列(模拟)

有一个序列,序列的第一个数是 n,后面的每个数是前一个数整除 2,请输出这个序列中值为正数的项。

输入格式
输入一行包含一个整数 n。

输出格式
输出一行,包含多个整数,相邻的整数之间用一个空格分隔,表示答案。

数据范围
1≤n≤1018
输入样例:
20
输出样例:
20 10 5 2 1

送分水题,之间模拟

n = int(input())

while n > 0:
print(n,end=' ')
n //= 2

二、解码(字符串)

小明有一串很长的英文字母,可能包含大写和小写。

在这串字母中,有很多连续的是重复的。

小明想了一个办法将这串字母表达得更短:将连续的几个相同字母写成字母 + 出现次数的形式。

例如,连续的 5 a,即 aaaaa,小明可以简写成 a5(也可能简写成 a4a、aa3a 等)。

对于这个例子:HHHellllloo,小明可以简写成 H3el5o2。

为了方便表达,小明不会将连续的超过 9 个相同的字符写成简写的形式。

现在给出简写后的字符串,请帮助小明还原成原来的串。

输入格式
输入一行包含一个字符串。

输出格式
输出一个字符串,表示还原后的串。

数据范围
输入字符串由大小写英文字母和数字组成,长度不超过 100
请注意原来的串长度可能超过 100

输入样例:
H3el5o2
输出样例:
HHHellllloo

这个题也挺水 就是字符串拼接

# O(N)
s = input().strip()
res = ''


for i in range(len(s)):
if not s[i].isdigit():
res += s[i]
else:
res += s[i-1] * (int(s[i]) - 1)
print(res)

不用内置方法

s = input().strip()

n = len(s)
res = ''
for i in range(n):
# 当前字符后面跟着数字
if i+1 < n and s[i+1] <='9': # s[i+1] 是数字字符
k = int(s[i+1])
while k:
res += s[i]
k -= 1
continue
if not '1' <=s[i] <= '9': # 当前字符后不跟数字 且当前字符不是数字
res += s[i]
print(res)

三、走方格(简单DP)

在平面上有一些二维的点阵。

这些点的编号就像二维数组的编号一样,从上到下依次为第 1 至第 n 行,从左到右依次为第 1 至第 m 列,每一个点可以用行号和列号来表示。

现在有个人站在第 1 行第 1 列,要走到第 n 行第 m 列。

只能向右或者向下走。

注意,如果行号和列数都是偶数,不能走入这一格中。

问有多少种方案。

输入格式
输入一行包含两个整数 n,m。

输出格式
输出一个整数,表示答案。

数据范围`在这里插入代码片`
1≤n,m≤30
输入样例1:
3 4
输出样例1:
2
输入样例2:
6 6
输出样例2:
0

简单的动态规划求数量

# O(N^2)
n,m = list(map(int,input().strip().split()))
N = 35
f = [[0 for i in range(N)] for j in range(N)] # 下标从1开始

f[1][1] = 1
for i in range(1,n+1):
for j in range(1,m+1):
if i % 2 or j % 2:
f[i][j] += f[i-1][j] + f[i][j-1]
print(f[n][m])

四、超级胶水(模拟)

小明有 n 颗石子,按顺序摆成一排。

他准备用胶水将这些石子粘在一起。

每颗石子有自己的重量,如果将两颗石子粘在一起,将合并成一颗新的石子,重量是这两颗石子的重量之和。

为了保证石子粘贴牢固,粘贴两颗石子所需要的胶水与两颗石子的重量乘积成正比,本题不考虑物理单位,认为所需要的胶水在数值上等于两颗石子重量的乘积。

每次合并,小明只能合并位置相邻的两颗石子,并将合并出的新石子放在原来的位置。

现在,小明想用最少的胶水将所有石子粘在一起,请帮助小明计算最少需要多少胶水。

输入格式
输入的第一行包含一个整数 n,表示初始时的石子数量。

第二行包含 n 个整数 w1,w2,,wn,依次表示每颗石子的重量。

输出格式
一个整数表示答案。

数据范围
1≤n≤105,
1≤wi≤1000
输入样例1:
3
3 4 5
输出样例1:
47
输入样例2:
8
1 5 2 6 3 7 4 8
输出样例2:
546

这个题的难点在于发现无论先合并哪两个石头,对胶水数量无影响

# 模拟 O(N) 关键是发现无论如何合并区间 答案都是唯一的
n = int(input())
lis = [int(i) for i in input().strip().split()]

res = 0
for i in range(n-1):
res += lis[i] * lis[i+1]
lis[i+1] += lis[i]
print(res)

五、整数拼接(枚举+哈希表)

给定一个长度为 n 的数组 A1,A2,⋅⋅⋅,An。

你可以从中选出两个数 Ai Aj(i 不等于 j),然后将 Ai Aj 一前一后拼成一个新的整数。

例如 12 345 可以拼成 12345 34512

注意交换 Ai Aj 的顺序总是被视为 2 种拼法,即便是 Ai=Aj 时。

请你计算有多少种拼法满足拼出的整数是 K 的倍数。

输入格式
第一行包含 2 个整数 n K。

第二行包含 n 个整数 A1,A2,⋅⋅⋅,An。

输出格式
一个整数代表答案。

数据范围
1≤n≤105,
1≤K≤105,
1≤Ai≤109
输入样例:
4 2
1 2 3 4
输出样例:
6

这题一开始做的时候我没想到最优解,就直接两重暴力
最后过了一半测试用例

# 暴力写法 O(N^2)
n,k = list(map(int,input().strip().split()))
lis = list(map(int,input().strip().split()))
cnt = 0
for i in range(n-1):
for j in range(i+1,n):
if int(str(lis[j])+str(lis[i])) % k == 0:
cnt += 1
if int(str(lis[i])+str(lis[j])) % k == 0:
cnt += 1
print(cnt)

有考虑到用哈希表 但是没想到怎么做,一开始还想的是会不会是力扣两数之和那种思路,没想出来.


举报

相关推荐

0 条评论