牛客——真题

1.序列找数

在这里插入图片描述

lst=list(map(int, input().split()))
def x(lst):
    for i in range(lst[0]):
        if i not in lst[1:]:
            return i
print(x(lst))

2.扭蛋机

在这里插入图片描述
这道题看着很难,其实就是从最后的值开始做,不停的往前倒就可以了,也可以直接简单的进行插入,最后在倒序输出就可以了。

n = int(input())
res = []
while n > 0:
    if (n-1)%2 == 0:
        res.append('2')
        n = (n-1)//2
    elif (n-2)%2 == 0:
        res.append('3')
        n = (n-2)//2
print(''.join(res[::-1]))

3.连续最大和

在这里插入图片描述

n=int(input())
lst=list(map(int,input().split()))
# 用while会因为不断的重新定义矩阵计算和导致计算量过大
res1=res=lst[0]
for i in lst:
    if res1<0:
        res1=i
    else:
        res1+=i
    res=max(res,res1)
print(res)

用while会因为不断的重新定义矩阵计算和导致计算量过大

n=int(input())
lst=list(map(int,input().split()))
res=lst[0]
arr=[lst[0]]
while right<n and left<=right:
    # 这个方法因为每次都要重新定义矩阵并且需要重新计算和,导致运算时间较长
    if x<0:
        left=right
    right+=1
    arr=lst[left:right]
    x=sum(arr)
    res=max(res,x)
print(res)

4.搬圆桌

在这里插入图片描述
这道题比较不好思考,可以直接用勾股定理做,直接计算距离,然后除以每次除以最长的移动距离2r。
while 是因为有些时候会输入多行数据

while True:
    try:
        r,x,y,x1,y1=map(int,input().split())
        l = ((x1-x)**2+(y1-y)**2)**0.5
        res = int(l//(2*r))
        print(res)
    except:
        break

5.最大乘积

在这里插入图片描述
1个讨巧的方法
在遍历数组是需要记录第一,第二,第三大,和最小,次小的数(负负的正)
但是暂时没看到更好的方法,需要注意的就是当全为负的时候其实是三个最小值的乘积才是最小,所以可能再加上一个012的乘积会更厉害一点

n=int(input())
lst=list(map(int,input().split()))
lst.sort()
print(max(lst[-1]*lst[-2]*lst[-3],lst[-1]*lst[0]*lst[1]))
# 这里max是为了避免有负值的时候 但是就是个讨巧的方法

6.最大差值

在这里插入图片描述
简单读一下题,要求的是后面的减前面的,如果是负值,就返回0
类似这种需要在遍历过程中寻找最小值的,就直接定义一个存储空间就可以了。
稍微仔细一点分析题目。

class Solution:
    def getDis(self , A: List[int], n: int) -> int:
        # write code here
        res,min_val=0,A[0]
        # min_val用于在遍历的过程中不断更新自己的最小值,可以用此来保证是用最小值在处理
        for i in range(1,n):
            res=max(res,A[i]-min_val)
            min_val=min(min_val,A[i])
        return res

7. 交叉线

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

def cross(a, b, c, d):
    if a > b:
        a, b = b, a
    if a < c < b and (d < a or d > b):# c d是不用判断大小的,因为c d谁大谁小都不重要 只要在内部就是交叉了
        # 相交的条件就是当前点在前面的点之内 这里判断的时候只放四个点进去 每次判断两根线
        # 但是没有判断第一根线和第2+根线之间的关系
        return True
    if a < d < b and (c < a or c > b):
        return True
    return False
 
def solve():
    n = int(input().strip())
    nums = list(map(int, input().split()))
    for i in range(n - 3):
        if cross(nums[i], nums[i+1], nums[i+2], nums[i+3]):
            print('y')
            return
    print('n')
    
    
T=int(input())
for i in range(T):
    solve()

8.火眼金睛

在这里插入图片描述
由于每个id的问题有多个人解答,考虑问题id作为key,解答的人id作为value,用set存储,如果有交集,则两个人都作弊,存到zuobi1集合,然后再查一遍,发现一个问题id有两个作弊的,存到zuobi2里面,合并两个zuobi集合就是最终集合;输出的时候注意格式就行

def zuobi(queue):
    res=set()
    for i in queue.keys():
        for j in queue[i]:
            if i in queue[j] and j in queue[i]:
                res.add(i)
                res.add(j)

    for i in queue.keys():
            if len(queue[i] & res)>=2:
                res.add(i)
    return res

while True:
    try:
        n=int(input())
        queue={}
        for i in range(n):
            lst=list(map(int,input().split()))
            queue[lst[0]]=set(lst[2:])
        res=zuobi(queue)
        print(len(res))
        for x in res:
            print(x,end=' ')
    except:
        break

上面这个方法的大bug就是没办法做一个人问两个问题的情况,要是每个人只提一个问题的话是可以做的。
解决办法其实很简单,无论他提了几个问题,都是他提的问题,所以可以直接在后面加上,然后set一下就可以了。


while True:
    try:
        n = int(input())
        cheat_list = []
        ans_dic = {}
        cheat_dic = {}
        for i in range(n):
            a =list(map(int,input().split()))
            if a[0] in ans_dic:
                # 这里在处理一个人问两个问题的情况 反正都是他问的 直接放一块就行了
                ans_dic[a[0]] += a[2:]
            else:
                ans_dic[a[0]] = a[2:]
            cheat_dic[a[0]] = 0

        for key, value in ans_dic.items():# 其他的方法大概一致
            for i in value:
                if i in ans_dic and i != key:
                    if key in ans_dic[i]:
                        cheat_list += [key, i]

        cheat_list = list(set(sorted(cheat_list)))

        for key, value in ans_dic.items():
            for i in cheat_list:
                if i in value:
                    cheat_dic[key] += 1

        for key, value in cheat_dic.items():
            if value >= 2:
                cheat_list.append(key)
        
        cheat_list = list(set(sorted(cheat_list)))
        print(len(cheat_list))
        if len(cheat_list) != 0:
            a = ' '.join(map(str, cheat_list))
            print(a)
    except:
        break

9.


1.


1.


1.


1.


1.


1.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值