目录
问题 A: 递归求和
问题 B: 又一道简单题
问题 C: 油田问题
问题 D: 文件存储
问题 E: 图的m着色问题
问题 F: 素数环
问题 G: 迷宫问题(回溯法求解)
问题 H: X星人的基因
题目描述
使用递归编写一个程序求如下表达式的计算结果: (1
输入n,输出表达式S(n)的结果。
输入
单组输入,输入一个正整数n,1 输出 输出表达式S(n)的计算结果。 思路:简单的递归题,题目已经给出了递归的公式,这里没使用递归 题目描述 输入一个四个数字组成的整数 n,你的任务是数一数有多少种方法,恰好修改一个数字,把它 变成一个完全平方数(不能把首位修改成 0)。比如 n=7844,有两种方法:3844=622 和 7744=882。 输入 输入第一行为整数 T (1<=T<=1000),即测试数据的组数,以后每行包含一个整数 n (1000<=n<=9999)。 输出 对于每组数据,输出恰好修改一个数字,把 n变成完全平方数的方案数 思路:题目要求首位不能修改为0,也就意味着变动范围就四位数的范围,用计算机稍微计算一下四位数开平方的上下界,然后遍历这个范围内的整数,将它们的平方和n对比即可。 题目描述 输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。如果两个字符“@”所在的格子相邻(横、竖或者对角线方向),即属于同一个八连块。 输入 输出 题目描述 如果有n个文件{F1,F2,F3,…,Fn}需要存放在大小为M的U盘中,文件i的大小为Si,1<=i<=n。请设计一个算法来提供一个存储方案,使得U盘中存储的文件数量最多。 输入 多组输入,对于每组测试数据,每1行的第1个数字表示U盘的容量M(以MB为单位,不超过256*1000MB),第2个数字表示待存储的文件个数n。 输出 输出最多可以存放的文件个数。 思路:高情商:贪心法,低情商:排个序,从最小的文件开始收集,直到收不了为止。 题目描述 给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的2个顶点着不同颜色,请输出着色方案。 输入 输入第一行包含n,m,k分别代表n个结点,m条边,k种颜色,接下来m行每行有2个数u,v表示u和v之间有一条无向边,可能出现自环边,所以请忽略自环边。 输出 输出所有不同的着色方案,且按照字典序从小到大输出方案。 思路:回溯法的经典问题,利用回溯法的思想解题即可。 题目描述 输入 输入正整数n。 输出 思路:回溯法的经典问题,利用回溯法的思想即可完成解题,回溯法的题目本质上就是剪枝函数和遍历方向不同。Tips:最后一位数插入之前,和当前path列表的首尾都要判断一次,因为题目要求的是一个环。 题目描述 输入一个n×n的迷宫,定义左上角为起点,右下角为终点,寻找一条从起点到终点的路径 输入 多组输入 输出 输出地图,用2表示路径 思路:经典的迷宫问题,修改一下剪枝函数和遍历方向即可。 题目描述 X星人的基因由A、B、C、D、E五种不同的结构组合而成。 输入 每一组测试数据包含3行, 输出 两个X星人是否可以结婚,如果可以输出”Yes“,如果不可以输出”No“。 思路:最长公共子序列的题目,按模板写即可,这里使用了滚动数组,不使用滚动数组也可。n = int(input())
a, b, res = 1, 4, 0
for i in range(0, n - 1):
res, a, b = res + a * b, b, (i + 3) ** 2
# print(a, b)
print(res)
问题 B: 又一道简单题
def check(x: int, y: int):
tmp = 0
while x > 0:
tmp = tmp + 1 if x % 10 != y % 10 else tmp
x, y = x // 10, y // 10
if tmp == 1:
return 1
else:
return 0
t, cnt = int(input()), 0
while t > cnt:
cnt, n, res = cnt + 1, int(input()), 0
for i in range(32, 100):
res = res + check(i ** 2, n)
print(f"Case {cnt}: {res}")
问题 C: 油田问题
输入行数m,以及列数n。
然后输入*和@
1<=n,m<=100
def dfs(x: int, y: int):
q = [[x, y]]
while q:
tx, ty = q.pop(0)
for d in directions:
dx, dy = tx + d[0], ty + d[1]
if 0 <= dx < m and 0 <= dy < n and maze[dx][dy] == '@' and visited[dx][dy] == 0:
visited[dx][dy], _ = cnt, q.insert(0, [dx, dy])
return
directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [1, -1], [-1, 1], [1, 1]]
while True:
try:
m, n = map(int, input().split())
maze, visited, cnt = [input().strip() for _ in range(m)], [[0] * n for _ in range(m)], 0
for i in range(m):
for j in range(n):
if maze[i][j] == '@' and visited[i][j] == 0:
visited[i][j], cnt = cnt + 1, cnt + 1
dfs(i, j)
# print(visited)
print(cnt)
except:
break
问题 D: 文件存储
第2行表示待存储的n个文件的大小(以MB为单位)。while True:
try:
m, n = map(int, input().split())
nums, cnt, res = [int(i) for i in input().split()], 0, 0
nums.sort()
for num in nums:
if num + res <= m:
cnt, res = cnt + 1, num + res
else:
break
print(cnt)
except:
break
问题 E: 图的m着色问题
def config(x: int, y: int):
for i in range(1, x):
if maze[i][x] == 1 and path[i - 1] == y:
return True
return False
def draw(x: int):
if x > n:
paths.append(path[:])
return
else:
for i in range(1, k + 1):
if not config(x, i):
path.append(i)
draw(x + 1)
path.pop()
return
while True:
try:
n, m, k = map(int, input().split())
maze, paths, path = [[0] * (n + 1) for _ in range(n + 1)], [], []
for _ in range(m):
a, b = map(int, input().split())
if a != b:
maze[a][b] = maze[b][a] = 1
draw(1)
paths.sort()
for path in paths:
for j in range(len(path)):
print(path[j], end='') if j == 0 else print('', path[j], end='')
print()
except:
break
问题 F: 素数环
注:每一个环都从1开始。
def check(index: int, x: int, y: int):
tmp = path[x] + y
for i in range(2, tmp // 2):
if tmp % i == 0:
return False
if index == n:
return True and check(-1, 0, y)
return True
def walk(x: int):
if x > n:
paths.append(path[:])
return
else:
for i in range(2, n + 1):
if i not in path and check(x, -1, i):
path.append(i)
walk(x + 1)
path.pop()
return
while True:
try:
n, paths, path = int(input()), [], [1]
walk(2)
paths.sort()
for path in paths:
for j in range(len(path)):
print(path[j], end='') if j == 0 else print('', path[j], end='')
print()
except:
break
问题 G: 迷宫问题(回溯法求解)
每组输入第一行有两个整数n,m表示迷宫尺寸
后跟n行,每行m个字符0表示道路,1表示墙壁
1<=n,m<=10
多个答案输出任意一种即可def walk(x: int, y: int):
if x == n - 1 and y == m - 1:
paths.append(path[:])
return
else:
for d in directions:
dx, dy = x + d[0], y + d[1]
if 0 <= dx < n and 0 <= dy < m and maze[dx][dy] == 0:
maze[dx][dy], _ = 2, path.append((dx, dy))
walk(dx, dy)
maze[dx][dy], _ = 0, path.pop()
return
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
while True:
try:
n, m = map(int, input().split())
maze, paths, path = [[int(i) for i in input().split()] for _ in range(n)], [], [(0, 0)]
walk(0, 0)
for i, j in paths[0]:
maze[i][j] = 2
for i in range(n):
for j in range(m):
print('', maze[i][j], end='') if j != 0 else print(maze[i][j], end='')
print()
except:
break
问题 H: X星人的基因
如果两个性别不同的X星人的基因序列相似度大于50%,按照X星的法律他们是禁止结婚的,等于50%据说还是可以的。
那么基因的相似度怎么计算呢?分别从两个人身上取长度均为N的基因片段,如果它们的最长公共子序列为M,则相似度=M/N。是不是很简单呢?
现在给你两段X星人的基因序列片段,请你判断他们是不是可以结婚?
第1行数字N表示待比较基因序列片段的长度,N<=10^3。
第2行和第3行为两个长度为N的基因序列片段。
输入0表示结束。while True:
try:
n = int(input())
DNA1, DNA2, dp = "".join(input().split()), "".join(input().split()), [[0] * (n + 1) for _ in range(2)]
# print(DNA1, DNA2)
for i in range(1, n + 1):
for j in range(1, n + 1):
dp[i % 2][j] = dp[(i - 1) % 2][j - 1] + 1 if DNA1[i - 1] == DNA2[j - 1] else max(dp[(i - 1) % 2][j], dp[i % 2][j - 1])
print('No') if dp[n % 2][n] / n > 0.5 else print("Yes")
except:
break