牛客真题刷2019(一)

目录

配比(体积配比,京东)

队列最小修改(排序思考,京东)

最长区间(字符串,京东)


配比(体积配比,京东)

题目描述

小M要制作一种黑暗饮料,这种饮料的原料有n种,编号为1-n,已知小M的容器最多容纳V升材料,黑暗料理的各种原料配比为 a1 : a2 : a3 : ... : an, 每种原料分别有b1,b2,... bn升。  问小M最多可以制作多少升这种饮料。小M使用的各种原料体积和不能超过V。

输入描述:

输入第一行,两个正整数n和V,表示原料种类数和容器容积。(1<=n<=1000,1<=V<=1000000) 输入第二行包含n个数a1,a2,a3,...an,表示n种原料的配比。 输入第三行包含n个数b1,b2,b3...bn,表示小M拥有的各种原料数。 (数字间以空格隔开)

输出描述:

输出包含一个非负数,表示小M最多可以制作多少饮料,结果保留4位小数。

示例1

输入

1 100
1
40

输出

40.0000

思路:

先把每种物质的体积数量和对应的比值相除这样是为了,假设配比是1:2:3,体积量为:20,40,20。那么我先求一个比值,20/1,表示按这种比例,第一份物质可以配20份。同理,第二种物质可以配40/2=20,也可以配20份的,同理第三种物质可以配20/3=9,可以最多配九份的量,那么综上所求,每配一份是需要各个物质都参与的,少了那个都不行,所以,以最少的为准,就是,这么多料,可以配9份,因为如果配九份以上,那么第三种,物质就不够用了。那么确定了这个之后,计算配九份所需要的体积,因为配九份,就相等于将第三份物质全部利用,那么第三种物质占其他物质的3/(1+2+3),那么就20*(1+2+3)/3,就是所需要的体积数了,如果这个数大于最大容量V,那就返回V,因为肯定可以把V给填满,如果不超过,那这个就是最大的了。

n,V = map(int, raw_input().split(' '))
a = map(float, raw_input().split(' '))
b = map(int, raw_input().split(' '))
temp = []
for a_i,b_i in zip(a,b):
    temp.append(b_i/a_i)
temp_sort = sorted(temp)
m_index = temp.index(temp_sort[0])
res = temp_sort[0] * sum(a)
if res > V:
    te_res = V
else:
    te_res = res
print str('%.4f'%te_res)

队列最小修改(排序思考,京东)

题目描述

已知一个奇怪的队列,这个队列中有n个数,初始状态时,顺序是1,2,3,4,…n,是1-n按顺序排列。这个队列只支持一种操作,就是把队列中的第i号元素提前到队首(1<i<=n),如有4个元素,初始为1,2,3,4,可以将3提前到队首,得到3,1,2,4 。  现在给出一个经过若干次操作之后的序列,请你找出这个序列至少是由原序列操作了多少次得到的。

输入描述:

第一行是一个整数n(1<=n<=10^5),表示序列中数字的数量。 接下来一行有n个数,是1-n的一个全排列。数字之间用空格隔开。

输出描述:

输出仅包含一个数字,表示至少操作了几次

示例1

输入

5
5 2 1 3 4

输出

2

思路
我的思路是,按照题目中的顺序逆向还原回去,因为原始排列顺序必定是值和下标对应相等的,那么从前开头往后遍历,如果这个值和下标不相等,我就把这个值提取出来,插入到这个下标等于这个值的位置上,依次类推,直至所有的值都等于其下标。但通过率只有20%。我很纳闷。

错误的原因是比如这个用例:10,9 5 8 4 3 6 2 10 1 7,当把后面的交换后,再更后面的就被挡住了,一直没办法往前进行,陷入了死循环。

正确的思路是利用后面的排序是没有被打乱的,依旧是顺序递增的关系,所以,从前往后遍历,只要遇到一个非递增关系,就可以确定,这个元素和之前的所有元素都要排一次,次数就是之间的元素数。

错误代码

n = input()
arr = map(int, raw_input().split(' '))
arr.insert(0,0)
count = 0
i = 1
while (i < n):
    while (arr[i] != i):
       arr.insert(arr[i]+1,arr[i])
       del arr[i]
       count += 1
    i += 1
print count

正确的代码

"""
利用后半部分已排序的性质,由后往前遍历,遇到不是nums[i] < nums[i-1]输出i即可
"""
 
n = int(input().strip())
nums = list(map(int, input().strip().split()))
ans, i , j =  0, 0, 0
 
if len(nums) <= 1:
    print(0)
    exit()
 
for i in range(n-1,1, -1):
    if nums[i] < nums[i-1]:
        print(i)
        exit()
 
print(0)

最长区间(字符串,京东)

题目描述

拉齐有一个01序列,他可以对这个序列进行任意多次变换,每次变换都是把序列的最后若干个元素放到最前面,例如:010011,将最后3个元素011放到最前面,序列变为011010。所有变换结束后,拉齐需要挑出一个全为1的连续区间,要求最大化区间长度。

输入描述:

共一行,一个01串,仅包含0或1。序列长度不超过50000。

输出描述:

一个整数,表示最长区间的长度。

示例1

输入

11011

输出

4

思考

这道题一开始是自己想解决的,但总是有错误,就看别人的思路,发现的确是人家考虑的全面,直接把两个字符串连在一起,然后,判断最长的1连续长度。然后,又错了,为啥嘞,如果是都是1的话,就出现两倍了,所以,看人家的思路,发现,人家是先判断是否是全1序列,如果不是,才进行后面的,还是人家的好啊。

错误的代码

while True:
    try:
        def solu(arr):
            ass = arr + arr
            count = 0
            maxs = 0

            if len(arr) <= 1:
                if arr[0] == 0:
                    return 0
                else:
                    return 1

            for i in range(len(ass)):
                if ass[i] == 1:
                    count += 1
                else:
                    if maxs < count:
                        maxs = count
                    count = 0
            return max(count,maxs)



        arr = map(int, raw_input())
        s = solu(arr)
        print s
    except:
        break

修改后的代码‘

while True:
    try:
        def solu(arr):
            ass = arr + arr
            count = 0
            maxs = 0

            if len(arr) <= 1:
                if arr[0] == 0:
                    return 0
                else:
                    return 1
            qq = [int(1) for w in range(len(ass))]
            if ass == qq:
                return len(ass)/2

            for i in range(len(ass)):
                if ass[i] == 1:
                    count += 1
                else:
                    if maxs < count:
                        maxs = count
                    count = 0
            return max(count,maxs)



        arr = map(int, raw_input())
        s = solu(arr)
        print s
    except:
        break

 

人家的正确的代码

def max_interval(num):
    if num=='1'*len(num):
        return len(num)
    num = num*2
    i,j = 0,0
    res = 0
    while i < len(num):
        while i<len(num) and num[i]=='1':
            i += 1
        res = max(res,i-j)
        i += 1
        j = i
    return res
if __name__=='__main__':
    s = raw_input().strip()
    print(max_interval(s))

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值