蓝桥杯真题又来了啊,上题目:
题目:有一个N*M的矩阵方格,其中有些方格中有奖品,有些方格中没有奖品。小蓝需要从N*M的矩阵中选择一个正方形区域,如果所选的正方形区域的一条对角线方格中有奖品,,就会获得所选对角线上所有奖品,否则不能获得奖品 当给出N和M的值,及N*M的矩形方格中摆放的奖品情况(0代表方格中没有奖品,1表示方格中有奖品),请你帮助小蓝找出一个正方形区域,能够获得数量最多的奖品,并将奖品数输出 如图,例如:N=5,M=6,奖品情况如下
自己画的,不好看,凑合着看吧
只要选择红线画上的正方形区域,就可以获得最多的4个奖品。
输入描述:第一行输入两个整数N 和 M,N表示矩形的行数,M表示矩阵的列数,两个整数之间一个空格隔开,接下来输入N行,每行包括M个0或者1,0或1之间一个空格隔开
输出描述:输出一个整数,表示最多可以获得的奖品数。
解析:这题直接暴力解,一共可以分为几个大块,第一、输入,第二、对角线遍历(可以考虑用函数)第三、输出结果
代码:第一种(非常好理解,但有点长)
n=input() # 输入行和列
N=int(n[0]) # 行就是第一个
M=int(n[2]) # 去掉空格来算,列是第三个
s=[] # 创建一个列表,里面要装所有的格子
d=0 # 输出结果(最长奖品对角线)
for i in range(N): # 搞N行的输入框
c=input()[::2] # 去掉空格
c=[int(i) for i in c] # 转成数字
s.append(c) # 装进大列表里
def find_left(i,j,s): # 进行左对角线寻找 i是行数索引号,j是列数索引号
global N # 把N搞成全局变量,要用一下它
h=1 # 对角线奖品数
if s[i][j] == 1: # 看看第一个是不是有礼物
while j > 0 and i<N-1: # 循环,达到对角线遍历的效果。j要注意不要等于零(后面j-1时会超出遍历范围)。i同理
# N要变成索引号得-1
i+=1 # 往下一列
j-=1 # 往左一格
if s[i][j] == 1: # 如果有礼物
h+=1 # 对角线奖品数+1
return h # 最终返回对角线奖品数量
else: # 如果第一个就没有奖品 就没有遍历的价值了
return 0; # 直接返回0
def find_right(i,j,s): # 进行右对角线寻找 和左对角线寻找方法一模一样
global N,M # 这回M也要用用
h=1
if s[i][j] == 1:
while j < M-1 and i<N-1: # M-1的道理和N-1的一样
i+=1
j+=1 # 往右一格
if s[i][j] == 1:
h+=1
return h
else:
return 0;
for i in range(N): # i是行索引号
for j in range(M): # j是列索引号
e=find_left(i,j,s) # 左边找找
f=find_right(i,j,s) # 右边也找找
d=e if e>d else f if f>d else d # 这里运用了一个三目运算符
# 返回e 得满足e>d。要不就是f 得满足f>d。都不是返回d
print(d)
这里面有两个小难点,第一是 i 和 j 的取值 ,我们在日常做题中也会遇到这种,这里给出的建议就是把自己当成电脑,一行一行自己搞一遍。第二是python里的三元运算符,有点难理解,按照注释一点一点推,会懂的。
代码第二种:采用递归算法
q=input() # 输入两个数 空格隔开
n=q[0] # 行数
N=int(n) # 转成整数
m=q[2] # 列数
M=int(m)
l1=[] # 保存二维列表 就是题中N*M格子
l=[] # 保存每次查找到的对角线上的奖品的个数
for i in range(N): # 遍历行
a = list(map(int, input().split(" "))) # 输入每行的奖品(1有奖 0无奖)
l1.append(a) # 整行保存到列表中
def find_l(l,x,y): # 从左到右查找奖品
global s
if l[x][y] == 1: # 判断是否有奖
s += 1 # 有奖就记上
x += 1
y += 1 # x,y 理解成坐标 方便下面的移动位置
if x <= 4 and y <= 5: # 判断是否在列表范围内
find_l(l,x,y) # 是! 就继续找
else:
return s # 递归的终止条件 返回找到的奖品本次数量
def find_r(l,x,y): # 从右侧往左侧找
global s1
if l[x][y] == 1:
s1 += 1
x += 1
y -= 1
if x <= 4 and 1 < y <= 5:
find_l(l,x,y)
else:
return s1
for i in range(N):
for j in range(M): # 整个矩形格子里的每一个小格子 预备好被查找
s = 0
s1=0
find_l(l1,i,j) # 从左到右找
l.append(s) # 找到的数量 保存到列表里
find_r(l1, i, j) # 从右到左找
l.append(s1) # 找到的数量 保存到列表里
print(max(l)) # 打印出找到最长那条线上的奖品数
好啦,就到这里,有什么疑问尽管评论区找我,下期分享更多蓝桥杯真题。
|