题目解析第四期来了,通过将一道一道题目的深度刨析,让我们一起培养我们的算法思维吧!
预告,本例题包含对矩阵的螺旋输出操作、逆鞍点的寻找等…
输入一个正整数n,要求输出n×n个数字构成的螺旋方阵。
输入格式: 首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入一个正整数n(0~20)。
输出格式: 对于每组测试,输出n×n的数字螺旋方阵。(各行数据间间隔6个字符宽度。)
第一步,“首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。”,我们读懂并且搞定输入:
T = eval(input())
for i in range(T):
n = eval(input())
第二步,“每组测试输入一个正整数n(0~20)”,限制n的数据范围:
if n>20:
print("error!")
else:
第三步,“输入一个正整数n,要求输出n×n个数字构成的螺旋方阵”,例如我们输入的n为2:
第一列 | 第二列 |
---|---|
4 | 3 |
2 | 1 |
我们需要完成上述效果。 | |
第四步,编写逻辑函数实现要求: | |
当输入n的值为0或者1的时候输出0和1: |
def spot(tup, x, y, num, n):
if n <= 0: return 0
if n == 1:
tup[x][y] = num
当n属于[2,20),我们需要逐行、逐列地对矩阵进行赋值,不难发现:
数据从下标为【0,0】的元素开始沿着逆时针减少。
第一行,向右移动,第一个下标x=0不变,第二个下标y=0增加:
for i in range(n):
tup[x][y + i] = num
num -= 1
最后一列,向下移动,第一个下标x=0增加,第二个坐标y=n-1不变:
for i in range(n - 1):
tup[x + 1 + i][y + n - 1] = num
num -= 1
最后一行,向左移动,第一个下标x=n-1不变,第二个下标y=n-2减少:
for i in range(n - 1):
tup[x + n - 1][y + n - 2 - i] = num
num -= 1
第一列,向上移动,第一个下标x=n-2开始减少,第二个下标y=0不变:
for i in range(n - 2):
tup[x + n - 2 - i][y] = num
num -= 1
第一圈即最外圈已经排完,接下来重复上述操作逐步向内:
spot(tup, x + 1, y + 1, num, n - 2)
完整代码:
def spot(tup, x, y, num, n):
if n <= 0: return 0
if n == 1:
tup[x][y] = num
for i in range(n):
tup[x][y + i] = num
num -= 1
for i in range(n - 1):
tup[x + 1 + i][y + n - 1] = num
num -= 1
for i in range(n - 1):
tup[x + n - 1][y + n - 2 - i] = num
num -= 1
for i in range(n - 2):
tup[x + n - 2 - i][y] = num
num -= 1
spot(tup, x + 1, y + 1, num, n - 2)
T = eval(input())
for i in range(T):
n = eval(input())
if n>20:
print("error!")
else:
ls = [[0] * n for i in range(n)]
spot(ls, 0, 0, n * n, n)
for x in ls:
print("%4d" * n % tuple(x))
求出n×m二维整数数组中的所有逆鞍点。这里的逆鞍点是指在其所在的行上最大,在其所在的列上最小的元素。若存在逆鞍点,则输出所有逆鞍点的值及其对应的行、列下标。若不存在逆鞍点,则输出“Not”。要求至少使用一个自定义函数。
输入格式: 测试数据有多组,处理到文件尾。每组测试的第一行输入n和m(都不大于100),第二行开始的n行每行输入m个整数。
输出格式:
对于每组测试,若存在逆鞍点,则按行号从小到大、同一行内按列号从小到大的顺序逐行输出每个逆鞍点的值和对应的行、列下标,每两个数据之间一个空格;若不存在逆鞍点,则在一行上输出“Not”(引号不必输出)。
第一步,分析题目输入输出,发现本题并没有说明以何种符号结束输入,于是我们选择while循环主体模式:
while True:
try:
n, m = map(int, input().split(" "))
if n>100 or m>100:
print("error!")
break
spot(n,m)
except:
break
第二步,题目分析:
第一列 | 第二列 | 第三列 | 第四列 |
---|---|---|---|
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
在这样一个矩阵中,我们需要输出4和4的坐标0,4。 | |||
第三步,逻辑代码实现; |
def spot(a,b):
line = {}
column = {}
for i in range(1, a + 1):
tmp = list(map(int, input().split()))
line[i] = tmp
tmp = []
for j in range(1, b + 1):
tmp = []
for i in range(1, a + 1):
tmp.append(line[i][j - 1])
column[j] = tmp
num = 0
for i in range(1, a + 1):
for j in range(1, b + 1):
if line[i][j - 1] == max(line[i]) and line[i][j - 1] == min(column[j]):
num += 1
print("{} {} {}".format(line[i][j - 1], i - 1, j - 1))
if num == 0:
print("Not")
完整代码:
def spot(a,b):
line = {}
column = {}
for i in range(1, a + 1):
tmp = list(map(int, input().split()))
line[i] = tmp
tmp = []
for j in range(1, b + 1):
tmp = []
for i in range(1, a + 1):
tmp.append(line[i][j - 1])
column[j] = tmp
num = 0
for i in range(1, a + 1):
for j in range(1, b + 1):
if line[i][j - 1] == max(line[i]) and line[i][j - 1] == min(column[j]):
num += 1
print("{} {} {}".format(line[i][j - 1], i - 1, j - 1))
if num == 0:
print("Not")
while True:
try:
n, m = map(int, input().split(" "))
if n>100 or m>100:
print("error!")
break
spot(n,m)
except:
break
对于一个奇数n阶方阵,请给出经过顺时针方向m次旋转后的结果。
输入格式:
测试数据有多组,处理到文件尾。每组测试的第一行输入2个整数n,m(1输出格式: 对于每组测试,输出奇数阶方阵经过m次顺时针方向旋转后的结果。每行中各数据之间留一个空格。
第一步,同样发现题目没有明确地输入结束标志,选则while结构。
第二步,输入格式;
题目中,要求n的值在(1,20)、m的值在[1,100];定义l列表运用map()函数将数插入。
n, m = map(int, input().split())
if 1<n<20 and 1<=m<=100:
l = list()
for i in range(n):
l.append(list(map(int, input().split())))
第三步,核心算法;
从右边逐步将每一列进行翻转,记得把翻转后的数据储存到一个新的空矩阵中!!!
for x in range(m):
data = []
for i in range(n):
t = []
for j in range(n):
t.insert(0, l[j][i])
data.append(list(t))
t.clear()
l = data
for i in range(n):
for j in range(n-1):
print(l[i][j], end=" ")
print(l[i][n-1])
完整代码:
while True:
try:
n, m = map(int, input().split())
if 1<n<20 and 1<=m<=100:
l = list()
for i in range(n):
l.append(list(map(int, input().split())))
for x in range(m):
data = []
for i in range(n):
t = []
for j in range(n):
t.insert(0, l[j][i])
data.append(list(t))
t.clear()
l = data
for i in range(n):
for j in range(n-1):
print(l[i][j], end=" ")
print(l[i][n-1])
else:
print("error!")
break
except:
break
输入整数m、p、n,再输入一个m行p列的整数矩阵A和一个p行n列的整数矩阵B,求两个矩阵的乘积AB
输入格式: 测试数据有多组,处理到文件尾。每组测试数据的第一行输入n(1
输出格式: 对于每组测试,输出m行,每行n个整数,表示AB的结果,每行中每两个数据之间留一个空格。
第一步,搞定输入格式要求:
m,p,n=map(int,input().split())
if 1<m<10 and 1<n<10 and 1<p<10:
第二步,创建两个行、列分别为(m,p)、(p,n)的矩阵,并为其输入值。
for i in range(m):
l.append(list(map(int,input().split())))
for i in range(p):
x.append(list(map(int,input().split())))
第三步,核心算法:
for i in range(m):
for u in range(n):
sum=0
for j in range(p):
pro=l[i][j]*x[j][u]
sum=sum+pro
完整代码:
while True:
try:
m,p,n=map(int,input().split())
if 1<m<10 and 1<n<10 and 1<p<10:
l=[]
x=[]
for i in range(m):
l.append(list(map(int,input().split())))
for i in range(p):
x.append(list(map(int,input().split())))
k=0
res=[[0]*n for i in range(m)]
for i in range(m):
for u in range(n):
sum=0
for j in range(p):
pro=l[i][j]*x[j][u]
sum=sum+pro
res[i][u]=sum
for x in res:
print(("%d " * n % tuple(x)).strip())
except:
break
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子, 假如兔子都不死,问每个月的兔子总数为多少?
第一个月 | 第二个月 | 第三个月 | 第四个月 | 第五个月 | 第六个月 |
---|---|---|---|---|---|
1对 | 1对 | 2对 | 3对 | 5对 | 8对 |
答案:
for i in range(1,22):
print ('%12ld %12ld' % (f1,f2), end=" ")
if (i % 3) == 0:
print ('')
f1 = f1 + f2
f2 = f1 + f2
判断1-100之间有多少个素数,并输出所有素数。
答案:
h = 0
leap = 1
from math import sqrt
for m in range(1,101):
k = int(sqrt(m + 1))
for i in range(2,k + 1):
if m % i == 0:
leap = 0
break
if leap == 1:
print ('%-4d' % m)
h += 1
if h % 10 == 0:
print ('')
leap = 1
print ('The number is %d' % h)
打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。
答案:
for n in range(100,1000):
i = n / 100
j = n / 10 % 10
k = n % 10
if n == i ** 3 + j ** 3 + k ** 3:
print(n)
i = n // 100
j = n // 10 % 10
k = n % 10
if n == i*i*i + j*j*j + k*k*k:
print(n)
例如:输入90,打印出90=233*5
答案:
def reduceNum(n):
if n in [1] :
print ('{}'.format(n))
while n not in [1] :
for index in range(2, n + 1) :
if n % index == 0:
n //= index
if n == 1:
print (index )
else :
print ('{} *'.format(index), end=" ")
break
reduceNum(90)
reduceNum(100)
输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
s = input('')
letters = 0
space = 0
digit = 0
others = 0
for c in s:
if c.isalpha():
letters += 1
elif c.isspace():
space += 1
elif c.isdigit():
digit += 1
else:
others += 1
print ('char = %d,space = %d,digit = %d,others = %d' % (letters,space,digit,others))
求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制。
答案:
from functools import reduce
Tn = 0
Sn = []
n = int(input('n = '))
a = int(input('a = '))
for count in range(n):
Tn = Tn + a
a = a * 10
Sn.append(Tn)
print (Tn)
Sn = reduce(lambda x,y : x + y,Sn)
print ("计算和为:",Sn)