版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
第一题
题目:假设用户a,b,c,如果a和b之间关系大于等于3,则a和b是一类;如果ab一类,bc一类,则abc一类,输入关系矩阵,返回类数。
思路:关系矩阵沿着对角线对称,因而只需要遍历(i, n) ,保存值大于等于3的关系,返回 n - 满足一类的长度,注意可能导致结果小于1,需要处理。
n = int(input())
line = []
for i in range(n):
line.append(list(map(int, input().split())))
ans = []
for i in range(n):
for j in range(i,n):
if line[i][j] >= 3:
ans.append([i,j])
count = n - len(ans)
count = max(count,1)
print(count)
第二题
题目:圆形花园入口有n个,修路时每个入口只能一条路,所有路不能相交。
思路:f(4) = 2, f(6) = 5, 发现正好是卡特兰数,h(0)=1,h(1)=1,递推式h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
本题的特殊性在于如果入口是奇数,则向下求整;入口小于1,则返回 0
def fun(n):
if n < 1:
return 0
if n == 1:
return 1
h = [0] * n
h[0], h[1] = 1, 1
for i in range(2, n):
h[i] = 0
for j in range(0,i):
h[i]+= h[j] * h[i-1-j]
return h[n//2] % 1000000007
a = int(input())
print(fun(a))
第三题
题目:2048,一个4x4的矩阵,上1下2左3右4运动,相同元素会合并且只会触发一次合并,且优先合并移动方向顶部的位置。
思路:把二维问题转化为一维解决,比如上下运动,其实就是对每一列操作,左右运动则是对每一行操作。操作的部分都是一模一样的,就是从顶部位置开始合并相同元素。[2,2,2,2] 往右边移动,这时候会变成[0,4,0,4] 需要去掉0,然后在左边加上缺失的0。最后在返回值时,上下运动需要转置数组。
由于顶部优先没有提前考虑,导致新程序运行时已提交了~~~(>_<)~~~,完整代码如下:
def fun(d, a):
ans = []
# 每一列处理
for i in range(4):
if d == 1 or d == 2:
# 取每一列
f = [_[i] for _ in a]
if d == 3 or d == 4:
# 取每一行
f = a[i]
if [_ for _ in f if _!=0] == []:
ans.append([0] * 4)
else:
# 优先从左边开始合并
if d == 1 or d == 3:
for i in range(len(f)-1):
if f[i] == f[i+1]:
f[i+1] = f[i] * 2
f[i] = 0
# 优先从右边开始合并
if d == 2 or d == 4:
for i in range(len(f)-2, -1, -1):
if f[i] == f[i+1]:
f[i+1] = f[i] * 2
f[i] = 0
# 去掉0
f = [_ for _ in f if _!=0]
# 后面 + 0
if d == 1 or d == 3:
f += [0] * (4-len(f))
# 前面 + 0
if d == 2 or d == 4:
f = [0] * (4-len(f)) + f
ans.append(f)
if d == 1 or d == 2:
# 行列转置
return list(map(list,zip(*ans)))
if d == 3 or d == 4:
return ans
print(fun(3,[[0,2,2,2],[0,2,2,2],[0,2,2,2],[0,2,2,2]]))
第四题
题目:糖果n个,如果糖果之间的最大公约数大于1,则两者有连接;求输出一个数,最多能得到多少糖果
思路:原始糖果数组的第一个元素放入新数组,然后依次判断原始数组的元素与新数组元素的最大公约数,如果满足条件则放入新数组,并在原始数组里面删除这些元素。每循环一次,判断一次新数组的长度
def hcf(x, y):
"""该函数返回两个数的最大公约数"""
num = 1
# 获取最小值
if x > y:
smaller = y
else:
smaller = x
for i in range(1, smaller + 1):
if (x % i == 0) and (y % i == 0):
num = i
return num
def fun(a):
res = 0
# 直到 原始数组为空
while a:
# 原始数组的第一个元素放入新数组
line = [a.pop(0)]
k = 0
while True:
# 如果满足条件则放入新数组
add_list = [i for i in a if hcf(i, line[k]) > 1]
line.extend(add_list)
# 在原始数组里面删除这些元素
for i in add_list:
a.remove(i)
# 从新数组的下一位元素开始遍历
k += 1
if k == len(line) - 1:
break
res = max(res, len(line))
# print(line)
return res
print(fun([20, 50, 22, 74, 9, 63]))