目录
问题 A: 牛牛的字符串
问题 B: 滚球游戏
问题 C: 数字三角形之动态规划法
问题 D: 绿地装饰
问题 E: 解密
问题 F: 整数划分问题之备忘录法
问题 G: 和费马开个玩笑
问题 H: 大还是小?
题目描述:
牛牛有两个字符串(可能包含空格),他想找出其中最长的公共连续子串的长度,希望你能帮助他。例如:两个字符串分别为"abede"和"abgde",结果为2。
输入:
每组数据包括两行,每行为一个字符串。
输出:
输出最长的公共连续子串的长度。
思路:最长连续公共子序列的模板题,maze[i][j]表示str1[i - 1]等于str2[j - 1]时公共连续字串的长度,res用来记录最大值。
while True:
try:
str1, str2 = input(), input()
len1, len2, maze, res = len(str1), len(str2), [], 0
for _ in range(len1 + 1):
maze.append([0] * (len2 + 1))
# print(maze)
for i in range(1, len1 + 1):
for j in range(1, len2 + 1):
if str1[i - 1] == str2[j - 1]:
maze[i][j] = maze[i - 1][j - 1] + 1
res = max(maze[i][j], res)
else:
maze[i][j] = 0
# print(maze)
print(res)
except:
break
题目描述:
某滚球游戏规则如下:球从入口处(第一层)开始向下滚动,每次可向下滚动一层,直到滚至最下面一层为止。球每次可滚至左下、下方或右下三个方格中的任意一个,每个方格都有一个得分,如样例所示。第1层有1个方格,第2层有3个方格,……,以此类推,第n层有2*n-1个方格。设计一个算法,使得球从入口滚至最下面一层的总得分和最大。
输入:
对于每个样例,第1行的正整数n表示数字三角形的行数。(n<=100)
接下来n行包含一个数字三角形,每一行包含2*n-1个方格,对应有2*n-1个表示得分的正整数(不超过10^5),每两个数字之间用空格隔开。
每两组样例之间有一个空行。
输出:
球从入口(第一层)滚至最下面一层的最大得分和。
思路:从最底层往上迭代,这样最顶层maze[0][0]就是我们的目标值,这道题需要注意一下的就是吸收输入中的空行,这里用flag标记到底是空行还是退出。
flag = 0
while True:
try:
n, maze, flag = int(input()), [], 1
for _ in range(n):
maze.append([int(i) for i in input().split()])
# print(maze)
for i in range(n - 2, -1, -1):
for j in range(2 * (i + 1) - 1):
maze[i][j] += max(maze[i + 1][j:j + 3])
print(maze[0][0])
except:
if flag == 1:
flag = 0
else:
break
题目描述:
如下图所示的数字三角形,从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。编写一个程序求出最佳路径上的数字之和。 【使用动态规划法实现】
7
3 8
8 1 2
2 7 4 4
4 5 2 6 5
输入:
多组样例输入,每组第一行输入三角形的层数n,接下来n行输入三角形。
输出:
输出最佳路径上的数字之和。
思路:从最底层往上迭代,这样最顶层maze[0][0]就是我们的目标值。
while True:
try:
n, maze = int(input()), []
for _ in range(n):
maze.append([int(i) for i in input().split()])
for i in range(n - 2, -1, -1):
for j in range(i + 1):
maze[i][j] += max(maze[i + 1][j], maze[i + 1][j + 1])
print(maze[0][0])
except:
break
题目描述:
湖南中医药大学坐落于中国历史文化名城长沙,是湖南省重点建设本科院校,是全国首批设立国家级重
点学科的高校,也是首批招收博士研究生、留学生及港澳台学生的中医药院校。学校现有 2 个校区,占
地面积 1393 亩,建筑面积 52 万平方米,主校区依岳麓南坡,临湘江西岸,环境幽雅,风光秀丽,是求
学成才的理想之地。
校园景观设计师小 W 的主要工作就是植被环境的设计维护,他有一个 N×N 的模板图,他创作景观的步
骤如下:
1、将当前的绿地分成 N×N 小块,再按照模板图添加装饰(黑色表示有装饰,白色表示没有);
2、对于每个白色(未被装饰)的地块,递归操作 1,应用模板图,即分成更小的 N×N 块,继续进行装
饰,而黑色(已装饰)的地块则不必操作。
下图是某次装饰过程的示意图。
现在你的任务是求出 K 次递归后的绿地状态。
输入:
单组数据。
第一行两个数 N,K,如题意中的描述。
接下来是一个 N×N 的模板图,’ . ’ 表示白色,’ * ’ 表示黑色。
2 ≤ n ≤ 3
1 ≤ k ≤ 5
输出:
输出一个 N K×N K 的矩阵表示答案,不允许有多余的空行或空格。
思路:先算出迭代K以后的地面到底有多大,然后根据模板进行递归修改即可,注意一下坐标换算。
def draw(x: int, y: int, length: int):
for i in range(x, x + length):
for j in range(y, y + length):
maze[i][j] = '*'
def dfs(x: int, y: int, length: int):
size = length // n
if size <= 0:
return
for i in range(n):
for j in range(n):
if model[i][j] == '*':
draw(x + i * size, y + j * size, size)
else:
dfs(x + i * size, y + j * size, size)
return
n, k = map(int, input().split())
model = [input().strip() for _ in range(n)]
maze = [['.'] * (n ** k) for _ in range(n ** k)]
dfs(0, 0, n ** k)
for m in maze:
print("".join(m))
题目描述:
湖南中医药大学有含浦、东塘 2 个校区,学校办学历史悠久,前身为 1934 年的湖南国医专科学校,1953
年创办湖南中医进修学校,1960 年创建普通高等本科院校——湖南中医学院,1979 年成为全国首批取得
中医类研究生学历教育资格的院校,1990 年原湖南科技大学成建制并入湖南中医学院,2002 年与湖南省
中医药研究院合并,2006 年经教育部批准更名为湖南中医药大学,2012 年进入湖南省一本招生序列。
目前,学校与湖南省中医药研究院实行校院合一的管理体制。学校学科门类齐全、中医药特色鲜明。学校
设有 18 个学院、24 个本科专业,涵盖医、理、工、管、文等 5 大学科门类。中医诊断学在本学科研究领
域居国内领先水平。
小 F 居住在含浦校区,他想和东塘校区的同学小 L 聊天,为了保证沟通安全,他发明了一种加密方式,这
种加密方式是这样的:对于一个 01 串,小 F 会将其从左到右每 8 位分成一组,最后一组可能不足 8 位,
对每组进行逆序操作,即如果原来是 bLbL+1bL+2 · · · bR−1bR, 逆序之后变成 bRbR−1bR−2 · · · bL−1bL。现在
小 F 已经加密好了一个串,并且将其发给了小 L,你能帮助小 L 得到这串密文对应的原始信息吗?
输入:
单组数据。
一行一个 01 串,代表加密后的字符串,串长度大于 0, 小于等于 100。
输出:
一行字符串,代表加密后的字符串所对应的原始信。
思路:模拟,每8位一翻转,注意一下一组不足8位的情况。
while True:
try:
strings = input().strip()
res, temp, cnt = "", "", 0
for s in strings:
res, cnt = s + res, cnt + 1
if cnt >= 8:
temp, cnt, res = f"{temp + res}", 0, ""
# print(cnt)
print(temp + res)
except:
break
题目描述:
使用备忘录法编写一个程序,求一个正整数n的所有划分个数。
例如,输入3,输出3;输入4,输出5。
输入:
多组输入,每一组是一个正整数n。
输出:
输出划分数。
思路:利用二维列表存储数据,自底向上计算,maze[n][m]表示整数n的加数最大不超过m的划分数 。
maze = [[1]]
while True:
try:
nums = int(input())
if nums >= len(maze):
for i1 in range(len(maze), nums + 1):
for j1 in range(i1 + 1):
if j1 == 0:
maze.append([0] * (i1 + 1))
else:
maze[i1][j1] = maze[i1][j1 - 1] + maze[i1 - j1][min(i1 - j1, j1)]
print(maze[nums][nums])
except:
break
题目描述:
费马大定理:当n>2时,不定方程an+bn=cn没有正整数解。比如a3+b3=c3没有正整数解。我们来给他开个玩笑:把方程改成a3+b3=c3,这样就有解了,比如a=4, b=9, c=79时43+93=793。
输入两个整数x, y, 求满足x<=a,b,c<=y的整数解的个数。
输入:
输入最多包含10组数据。每组数据包含两个整数x, y(1<=x,y<=108)。
输出:
对于每组数据,输出解的个数。
思路:双重循环判断,注意结束条件。
cnt = 0
while True:
try:
x, y = map(int, input().split())
res, cnt = 0, cnt + 1
for a in range(x, min(y + 1, 1001)):
for b in range(x, a + 1):
n = a ** 3 + b ** 3
if n % 10 == 3 and x <= n // 10 <= y:
# print(a, b, n)
res = res + 2 if a != b else res + 1
print(f"Case {cnt}: {res}")
except:
break
题目描述:
输入两个实数,判断第一个数大,第二个数大还是一样大。每个数的格式为:
[整数部分].[小数部分]
简单起见,整数部分和小数部分都保证非空,且整数部分不会有前导 0。不过,小数部分的最 后可以有 0,因此 0.0和 0.000是一样大的。
输入:
输入包含不超过 20组数据。每组数据包含一行,有两个实数(格式如前所述)。每个实数都 包含不超过 100个字符。
输出:
对于每组数据,如果第一个数大,输出"Bigger"。如果第一个数小,输出"Smaller"。如果两个 数相同,输出"Same"。
思路:因为整数部分没有前导0,所以可以通过判断整数部分的长度初步判断大小。如果长度相等再判断整数的数值大小,还相等的话,再将小数部分对齐补0,判断大小。
def init():
global df1, df2
if length3 < length4:
df1 = df1 + "0" * (length4 - length3)
else:
df2 = df2 + "0" * (length3 - length4)
def check(str1: str, str2: str, n: int):
for i in range(n):
if str1[i] < str2[i]:
return -1
if str1[i] > str2[i]:
return 1
return 0
cnt = 0
while True:
try:
string1, string2 = input().split()
i1, df1 = string1.split('.')
i2, df2 = string2.split('.')
length1, length2, length3, length4 = len(i1), len(i2), len(df1), len(df2)
init()
k, ctl = check(i1, i2, length1), check(df1, df2, max(length3, length4))
# print(1)
if length1 < length2 or k == -1 or (k == 0 and ctl == -1):
res = "Smaller"
elif length1 > length2 or k == 1 or (k == 0 and ctl == 1):
res = "Bigger"
else:
res = "Same"
cnt += 1
print(f"Case {cnt}: {res}")
except:
break