Python-天梯赛第八届L1-L2详细题解

 L1-1 最好的文档

print("Good code is its own best documentation.")

L1-2 什么是机器学习

a,b=map(int,input().split())
ans=a+b
print(ans-16)
print(ans-3)
print(ans-1)
print(ans)

L1-3 程序员买包子

n,x,m,k=input().split()
if(k==n):
    print(f"mei you mai {x} de")
elif(k==m):
    print(f"kan dao le mai {x} de")
else:
    print(f"wang le zhao mai {x} de")

L1-4 进化论 

n=int(input())
for i in range(n):
    A,B,C=map(int,input().split())
    if(C==A*B):
        print("Lv Yan")
    elif(C==A+B):
        print("Tu Dou")
    else:
        print("zhe du shi sha ya!")

L1-5 猜帽子游戏 

n=int(input())
color=list(map(int,input().split()))
k=int(input())
for i in range(k):
    answer=list(map(int,input().split()))
    flag = 1
    #全都弃权
    if (answer.count(0) == n):
        flag = 0
    else:
        for j in range(n):
            if answer[j]==0:
                continue
            #有一个答案错误
            if(answer[j]!=color[j]):
                flag=0
                break
        
    if(flag):
        print("Da Jiang!!!")
    else:
        print("Ai Ya")

L1-6 剪切粘贴

这道题我觉得坑在一定是连续的前后缀,不能分开,所以find的时候一定要把开头和结尾加起来找

s = input().strip()
n = int(input())
for _ in range(n):
    parts = input().strip().split()
    a = int(parts[0])
    b = int(parts[1])
    s1 = parts[2]
    s2 = parts[3]

    # 提取s3并删除原位置的子串
    s3 = s[a - 1:b]
    s = s[:a - 1] + s[b:]

    # 查找目标位置  s1,s2连在一起的 不能中间隔开
    target = s1 + s2
    pos = s.find(target)
     #能找到
    if pos != -1:
        # 在s1和s2之间插入s3
        insert_pos = pos + len(s1)
        s = s[:insert_pos] + s3 + s[insert_pos:]
    else:
        # 找不到追加到末尾
        s += s3
print(s)

L1-7 分寝室

 在枚举x的取值得到y的值时,还要检查y是否满足要求

n0,n1,n=map(int,input().split())
def f(x):
    factors=[]
    #枚举宿舍间数
    for i in range(1,n+1):
        #如果能被人数整除 那么每间宿舍x//i个人 不允许单人间
        if x%i==0 and x!=i:
            factors.append(i)
    return factors

factors=f(n0)
if factors==[]:
    print('No Solution')
else:
    ans=float('inf')
    a,b=0,0
    flag=0
    for x in factors:
        #另一个性别的学生的宿舍间数
        y=n-x
        #如果不能平均分配 continue
        if n1%y!=0:continue
        flag=1
        diff=abs(n0// x - n1// y)
        if diff<ans:
            ans=diff
            a=x
            b=y
    if flag:
        print(a,b)
    else:
        print('No Solution')

L1-8 谁管谁叫爹

n=int(input())
for i in range(n):
    a,b=map(int,input().split())
    sa=sum(list(map(int,str(a))))
    sb=sum(list(map(int,str(b))))
    #同时满足或同时不满足
    if (a%sb==0 and b%sa==0) or (a%sb!=0 and b%sa!=0):
        print('A' if a > b else 'B')
    else:
        if a%sb==0:
            print('A')
        elif b%sa==0:
            print('B')

L2-1 堆宝塔

n=int(input())
#抓取的顺序  直径
a=list(map(int,input().split()))
cnt=0
A=[]
B=[]
A.append(a.pop(0))
max_size=0
while a:
    num=a.pop(0)
    #如果取出来的num 小于 A的最后一个
    if num<A[-1]:
        A.append(num)
    else:
        #B不为空 且 B的最后的一个小于num
        if B==[] or B[-1]<num:
            B.append(num)
        else:
            #否则取下来作为一个成品
            cnt+=1
            #更新最大层数 A重置为空
            max_size=max(max_size,len(A))
            A=[]
            #当B不为零 且 B的最后一个大于num 取出来放到A中 最后把num也放在A上
            while B and B[-1]>num:
                A.append(B.pop())
            A.append(num)
#最后记得检查A和B中还有没有
if A:
    cnt+=1
    max_size = max(max_size, len(A))
if B:
    cnt+=1
    max_size = max(max_size, len(A))
print(cnt,max_size)

 

L2-2 天梯赛的赛场安排

 

字好多,看着就头大。 这道题的坑点我觉得在“每一轮”,是对当前轮的排序,下一轮的排序只属于下一轮,不能插到这一轮。其实可以在输入的时候就得到每一个学校需要的监考人数了(教室数),主要是要得到总的教室数,有多个学校共用一个教室的情况,所以不能简单叠加。

将多余的人插入堆中,python默认小根堆,所以记得加负号变为大根堆,最后取出来再取反。

考场剩余容量保持有序,因为我要知道当前剩余量是否足够坐下该学校的剩余人数,不够要重开。当我将考场剩余容量保持有序时,只用判断当前数组最后一个是否够,不够就新开。再更新容量的同时也用到二分插入,动态更新剩余容量。全过轻轻松松!

import sys
input = sys.stdin.readline
import heapq
import bisect
#学校个数 考场容量
n, c = map(int, input().split())
#最大堆 存剩余人数
hp=[]
#考场剩余容量
remain_c=[]
# 列表存储每个学校的详细信息
schools = []
#考场总数
tot=0
for _ in range(n):
    sn, num = input().split()
    num=int(num)
    #考场数量
    cnt=num//c
    tot+=cnt
    cnt+=(0 if num%c==0 else 1)
    print(sn,cnt)
    if num%c!=0:
        heapq.heappush(hp,-(num%c))
while hp:
    remain=-heapq.heappop(hp)
    idx=bisect.bisect_right(remain_c,remain)
    #如果没有刚刚好的 
    if remain not in remain_c :
        #比最大的还大 就新开一个
        if idx==len(remain_c):
            tot+=1
            new_idx=bisect.bisect_right(remain_c,c-remain)
            remain_c.insert(new_idx,c-remain)
        else:
            #否则就在进相应考场 容量减去相应人数
            val=remain_c.pop(idx)-remain
            if val!=0:
                new_idx=bisect.bisect_right(remain_c,val)
                remain_c.insert(new_idx,val)
    else:
        #有刚刚好的就直接放进去 容量为零pop掉
        idx=idx-1
        remain_c.pop(idx)

print(tot)

 

 L2-3 锦标赛

 

 这一道题我觉得是最难的,不是时间超时就是内存超限,大家有能全部通过的方法,欢迎分享!

import sys
sys.setrecursionlimit(100000)
input=sys.stdin.readline
k = int(input())
# 计算最大节点数,树的高度为 k+1
max_nodes = 2**(k+1)
# 初始化所有节点的 win 和 lose 值为 0
tree = [{'win': 0, 'lose': 0} for _ in range(max_nodes)]

# 从叶子节点到根节点逐层读取 lose 值
for i in range(k, 0, -1):
    start = 2**(i-1)  # 当前层的起始节点索引
    values = list(map(int, input().split()))  # 读取当前层的 lose 值
    for idx, val in enumerate(values, start):
        tree[idx]['lose'] = val  # 将 lose 值赋给对应的节点

root_val = int(input())
tree[1]['win'] = root_val

def check(n):
    if n >= 2**k:  # 如果当前节点是叶子节点
        return True
    else:
        # 如果当前节点的 lose 值大于 win 值,则不满足条件
        if tree[n]['lose'] > tree[n]['win']:
            return False
        else:
            left = 2 * n  # 左子节点索引
            right = 2 * n + 1  # 右子节点索引
            # 将当前节点的 win 值赋给左子节点
            tree[left]['win'] = tree[n]['win']
            # 将当前节点的 lose 值赋给右子节点
            tree[right]['win'] = tree[n]['lose']
            # 递归检查左子树和右子树
            if check(left) and check(right):
                return True

            # 交换左右子节点的 win 值
            tree[left]['win'], tree[right]['win'] = tree[right]['win'], tree[left]['win']
            # 再次递归检查左子树和右子树
            if check(left) and check(right):
                return True
            return False

# 检查从根节点开始的子树是否满足条件
if check(1):
    # 输出所有叶子节点的 win 值
    for i in range(2**k, 2**(k+1)):
        if i == 2**(k+1) - 1:
            print(tree[i]['win'])
        else:
            print(tree[i]['win'], end=' ')
else:
    # 如果不满足条件,输出 "No Solution"
    print('No Solution')

L2-4 寻宝图

 其实这道题考察的就是很规范的dfs,一个是连通量,一个是特殊点的标记

import sys
sys.setrecursionlimit(100000)
input=sys.stdin.readline
n,m=map(int,input().split())
Map=[]
for i in range(n):
    Map.append(input())
#岛屿总数量ans  宝藏总数量cnt
ans=0
cnt=0
vis=[[0]*m for i in range(n)]
def dfs(x,y):
    vis[x][y] = 1
    if Map[x][y]!='1':
        global flag
        flag=1
    for deltax,deltay in [(1,0),(0,1),(-1,0),(0,-1)]:
        xx, yy = deltax + x, deltay + y
        if 0<=xx<n and 0<=yy<m and vis[xx][yy]==0 and Map[xx][yy]!='0':
            dfs(xx,yy)

for i in range(n):
    for j in range(m):
        if vis[i][j]==0 and Map[i][j]!='0':
            flag=0
            dfs(i,j)
            ans+=1
            if flag==1:cnt+=1
print(ans,cnt)

 

ps:python真的太难了,其他语言能轻松过的,python要疯狂注意时间和空间!!!

发现L2中总有两道更复杂更难写的,不是题目难就是题目复杂绕弯多,字一堆,看着就晕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值