实验内容
杨辉三角就是一个用数排列起来的三角形(如下图),杨辉三角规则如下:
1)每行第一个数和最后一个数都为1,其它每个数等于它左上方和右上方的两数之和;
2)第n行有n个数。
注意:“列”指的是如图所标注的斜列。
编程实现:
小青对杨辉三角的特点和规律研究得很明白,现要考察你对杨辉三角的熟悉程度,首先告知你这是一个N行的杨辉三角,然后又告知了两个数值X和Y(X表示第几行,Y表示第几列),让你根据杨辉三角的特点和观察到的规律解决以下两个问题。
1)第X行第Y列对应的数是多少;
2)求出N行的杨辉三角中第Y列中所有数的和。
思路1(递归):
杨辉三角的特性及其产生就可以用递归解释,每一行的首尾都为1,其他的数是根据上一行相同位置和上一行的相同位置的前一位置相加得来的,则我很容易想到了递归解决,当列数为1时即为一行的首,返回1当行数等于列数时即为一行的尾,返回1,其他的数则返回上一行相同位置和上一行的相同位置的前一位置相加的值即可求得每一个想求得位置的值。
则解决第一题直接查询即可,解决第二题使列数不变,利用循环当行数大于等于列数时加起来即可
优点:容易想到,实现起来不复杂。
缺点:在面对查询数据过大时,时间极长,易超时。
代码:
#利用递归方法解决
def yanghui_value(x,y):#递归函数
if y==1:
return 1#若是一行的头那么值为1
if x==y:
return 1#若是一行的尾那么值为1
else :
return yanghui_value(x-1,y)+yanghui_value(x-1,y-1)#若不是一行的头或尾,它的值是上一行的同样的位置与上一行前一个位置的和
#输入行数
while 1:
try:
N=int(input('请问这是一个几行的杨辉三角呢?请输入您的答案:'))
if N<=0:
print('请输入正确的大于0的数字!!!')
continue
break
except:
print('您输入的有错误!!!')
print()
#查找某一行某一列具体的值
while 1:
try:
X, Y = map(int, input('请输入行标和列标(行标需大于等于列标)(且均要小于您要求杨辉三角的行数):').split())
if(X>N or Y>N):#只有当N<=X且N<=Y时才会在杨辉三角中存在值为接下来的求出N行的杨辉三角中第Y列中所有数的和做准备
print('行标和列标均要小于您要求杨辉三角的行数!!!')
continue
if (X<Y):
print('行标需大于等于列标!!!')
continue
print('\n杨辉三角第%d行第%d列的值为:%d'%(X,Y,yanghui_value(X,Y)))
break
except:
print('您输入的有错误!!!')
#求出N行的杨辉三角中第Y列中所有数的和。
column_sum=0
for k in range(Y,N+1):#只有当n<=x时才会在杨辉三角中存在值
column_sum += yanghui_value(k,Y)
print('%d行的杨辉三角中第%d列中所有数的和为:%d'%(N,Y,column_sum))
运行结果:
第一组:
第二组:
第三组:
思路2(公式):
杨辉三角可以用公式求其某一行某一列的值,
value(m,n)=C(m-1,n-1)则用此公式解决
解决第一题直接查询即可,解决第二题使列数不变,利用循环当行数大于等于列数时加起来即可
优点:所需时间短(其时间复杂度与所查询的列数线性相关),对比递归,面对庞大的数据仍然不会超时。
缺点:几乎无缺点,我暂时没找到缺点。
代码:
#利用公式法求解
def yanghui_value(x, y):
if x<y:
return False
x-=1#因公式为C(x-1,y-1)则x要先处理一下,下面的y不处理因为range函数左闭右开,y取不到只能取到y-1
result = 1
for i in range(1, y):#杨辉三角求某一行某一列的公式
result = result * (x - i + 1) // i
return result
#输入行数
while 1:
try:
N=int(input('请问这是一个几行的杨辉三角呢?请输入您的答案:'))
if N<=0:
print('请输入正确的大于0的数字!!!')
continue
break
except:
print('您输入的有错误!!!')
print()
#查找某一行某一列具体的值
while 1:
try:
X, Y = map(int, input('请输入行标和列标(行标需大于等于列标)(且均要小于您要求杨辉三角的行数):').split())
if(X>N or Y>N):#只有当N<=X且N<=Y时才会在杨辉三角中存在值为接下来的求出N行的杨辉三角中第Y列中所有数的和做准备
print('行标和列标均要小于您要求杨辉三角的行数!!!')
continue
if (X<Y):
print('行标需大于等于列标!!!')
continue
print('\n杨辉三角第%d行第%d列的值为:%d'%(X,Y,yanghui_value(X,Y)))
break
except:
print('您输入的有错误!!!')
#求出N行的杨辉三角中第Y列中所有数的和。
column_sum=0
for k in range(Y,N+1):#只有当n<=x时才会在杨辉三角中存在值
column_sum += yanghui_value(k,Y)
print('%d行的杨辉三角中第%d列中所有数的和为:%d'%(N,Y,column_sum))
运行结果:
第一组:
第二组:
第三组:
工人砌了一面奇特的砖墙,该墙由N列砖组成(1≤N≤106),且每列砖的数量为Ki(1≤Ki≤104,相邻两列砖之间无缝隙),每块砖的长宽高都为1。
小蓝为了美化这面墙,需要在这面墙中找到一块面积最大的矩形用于涂鸦,那么请你帮助小蓝找出最大矩形,并输出其面积。
例如:N = 6,表示这面墙有6列,每列砖的数量依次为3、2、1、5、6、2,如下图:
图中虚线部分是一块面积最大的矩形,其面积为10。
输入描述
第一行输入一个正整数N(1≤N≤10^6),表示这面砖墙由几列砖组成
第二行输入N个正整数Ki(1≤Ki≤10^4),表示每列砖的数量,正整数之间以一个空格隔开
输出描述
输出一个正整数,表示最大矩形的面积,同时输出墙所在起始位置。
思路:
我先让用户输入总共有多少列砖,再让其输入每列砖的个数,存储在列表中。
依次从每块砖开始向后遍历(即先进入循环遍历每一块砖,在这个循环底下再嵌套一个循环,让其从当前遍历到的砖向后依次遍历)这样可以查到所有的组合,在每次遍历时,寻找此区间内的最小值,再将最小值乘上当前的砖与遍历到的砖的距离,即可获得当前的矩形,与此前记录的矩形面积对比,若超过此前矩形面积(初始值为-1),记录下面积与当前遍历开始的砖的位置。最后再输出即可。
代码:
while 1:
try:
N = int(input('请输入有几列砖:'))
if N<=0:
print('输入的砖的列数不能小于等于0哦!!!')
continue
break
except:
print('您的输入有问题!!!')
while 1:
try:
bricks = list(map(int, input('请输入每一列砖的个数(用空格隔开):').split()))
for k in bricks:
p=0
if k<0:
print('一列砖不能有个数小于0的!!!请重新输入!!!')
p=1
break
if p==1:
continue
if not len(bricks)==N:
print('每一列砖必须都要有个数!!!请重新输入!!!')
continue
break
except:
print('您的输入有问题!!!')
area=-1 #保证在砖的个数为0时也能记录
loc=-1
for i in range(N):
for k in range(i+1,N+1):
number=min(bricks[i:k])
now_area=number*(k-i)
if now_area>area:
area=now_area
loc=i
print()
print('最大矩形的面积为:',area)
print('墙所在起始位置(若面积相同时保留最前面的位置):',loc+1)
运行结果:
第一组:
第二组:
第三组:
第四组: