百度2017春招笔试真题编程题集合--Python

Posted zy_dream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了百度2017春招笔试真题编程题集合--Python相关的知识,希望对你有一定的参考价值。

注:笔试题摘自牛客网,一共五道编程题。以下包括题目描述,个人思路,正确结果

1.

度度熊想去商场买一顶帽子,商场里有N顶帽子,有些帽子的价格可能相同。度度熊想买一顶价格第三便宜的帽子,问第三便宜的帽子价格是多少? 

输入描述:
首先输入一个正整数N(N <= 50),接下来输入N个数表示每顶帽子的价格(价格均是正整数,且小于等于1000)


输出描述:
如果存在第三便宜的帽子,请输出这个价格是多少,否则输出-1

输入例子:
10
10 10 10 10 20 20 30 30 40 40

输出例子:
30

个人思路:

读完这道题,脑子里面大致想了一下思路,觉得还是挺简单的,用 list 和 set  以及 sorted 最后成功完成测试。

一看到价格可能相同的字眼,set 就瞬间出现在眼前。

正确答案(本人 && 牛客游客):

n = int(raw_input())
arr = [int(i) for i in raw_input().strip().split()]
result = sorted(list(set(arr)))
if len(result) < 3:
    print -1
else:
    print result[2]
接下来放上的这名无名游客的代码,思路和我的大致一样

content = raw_input()
data = raw_input()
price = data.split(" ")
price = list(set(price))
price = map(eval, price)
price = sorted(price)
 
print price[2] if len(price) > 2 else -1
重点是想学习人家的最后一句,大家懂得。


2.

一个数轴上共有N个点,第一个点的坐标是度度熊现在位置,第N-1个点是度度熊的家。现在他需要依次的从0号坐标走到N-1号坐标。
但是除了0号坐标和N-1号坐标,他可以在其余的N-2个坐标中选出一个点,并直接将这个点忽略掉,问度度熊回家至少走多少距离? 

输入描述:
输入一个正整数N, N <= 50。

接下来N个整数表示坐标,正数表示X轴的正方向,负数表示X轴的负方向。绝对值小于等于100


输出描述:
输出一个整数表示度度熊最少需要走的距离。

输入例子:
4
1 4 -1 3

输出例子:
4

个人思路:

度度熊这题我是写出来了,测试也完成通过。但回头看写的代码太多了,还是没找到很简单的方法。

反正当时想的是找出中间数,前后距离最大的那个数字,干掉之。

正确答案(牛客网 id:C_Niels):

while True:
    try:
        n = int(raw_input())
        coords = map(int, raw_input().split())
        sums = 0
        max_saved_len = 0
        for i in range(1, n):
            sums += abs(coords[i]-coords[i-1])
        for i in range(1, n-1):
            temp = abs(coords[i-1]-coords[i])+abs(coords[i]-coords[i+1])-abs(coords[i-1]-coords[i+1])
            if temp > max_saved_len:
                max_saved_len = temp
        print(sums-max_saved_len)
    except:
        break
这个果然是用 temp 来找一个书前后相加最大的值,最后减去。人家这个好简洁!我的那个太绕了

        if arr[i] >= 0 and arr[i-1] >= 0 and arr[i+1] >= 0 or arr[i] < 0 and arr[i-1] < 0 and arr[i+1] < 0:
            d1 = abs(arr[i]) - abs(arr[i-1])
            d2 = abs(arr[i]) - abs(arr[i+1])
            dis.append(abs(d1)+abs(d2))
我的冰山一角,真的不忍放出我的代码了。


3.

三维空间中有N个点,每个点可能是三种颜色的其中之一,三种颜色分别是红绿蓝,分别用'R', 'G', 'B'表示。 
现在要找出三个点,并组成一个三角形,使得这个三角形的面积最大。
但是三角形必须满足:三个点的颜色要么全部相同,要么全部不同。 

输入描述:
首先输入一个正整数N三维坐标系内的点的个数.(N <= 50) 

接下来N行,每一行输入 c x y z,c为'R', 'G', 'B' 的其中一个。x,y,z是该点的坐标。(坐标均是0到999之间的整数)


输出描述:
输出一个数表示最大的三角形面积,保留5位小数。

输入例子:
5
R 0 0 0
R 0 4 0
R 0 0 3
G 92 14 7
G 12 16 8

输出例子:
6.00000

个人思路:

1.三维空间知道求三角形的面积,不知道公式或者怎么算,gg
2.要找三点颜色相同或者不同的情况
3.N必须大于等于3,且判断输入的情况是否能构成要求的三角形
1.
用两点间的距离公式算出三边长a,b,c,再用海伦公式计算.
面积S=根号(p*(p-a)*(p-b)*(p-c)) 其中p=(a+b+c)/2.
面积要最大,即 p 最大
2.
所有可能性,排列组合啊,很难啊这题
三点,求三边,然后才求面积
三边最大,面积最大
最终思路:源于网上大佬提供
先以三个点来求面积,
然后不断加入一个点,不断更新位置
虽然现在写完了,逻辑思路感觉也没什么问题
但其实,还是时间复杂度的问题
这题现在我还是想看看网上的正确答案,看他们是怎么简单的实现

正确答案(牛客网 id:西红柿番茄炒蛋)

import math
def CalLen(A,B,C):
    ABvalue = (A[1] - B[1]) ** 2 + (A[2] - B[2]) ** 2 + (A[3] - B[3]) ** 2
    AB = math.sqrt(ABvalue)
    ACvalue = (A[1] - C[1]) ** 2 + (A[2] - C[2]) ** 2 + (A[3] - C[3]) ** 2
    AC = math.sqrt(ACvalue)
    BCvalue = (B[1] - C[1]) ** 2 + (B[2] - C[2]) ** 2 + (B[3] - C[3]) ** 2
    BC = math.sqrt(BCvalue)
    return (AB,AC,BC)
 
if __name__ == '__main__':
    N = int(raw_input())
    data = []
    dLen = []
    max_S = 0
    for i in range(N):
        data.append([k for k in raw_input().split()])
        for j in range(1,4):
            data[i][j] = int(data[i][j])
    point = []
    for i in range(N - 2):
        for j in range(i+1,N-1):
            for k in range(1+j,N):
                A = data[i]
                B = data[j]
                C = data[k]
                point.append([A,B,C])
    for i in range(len(point)):
        AB,AC,BC = CalLen(point[i][0],point[i][1],point[i][2])
        #dLen.append([AB,AC,BC])
        if (AB+AC)>BC and (AB+BC)>AC and (AC+BC)>AB:
            if (point[i][0][0] == point[i][1][0] and point[i][1][0] == point[i][2][0]) or (point[i][0][0] != point[i][1][0] and point[i][0][0] != point[i][2][0] and point[i][1][0] != point[i][2][0]):
                dLen.append([AB,AC,BC])
    for i in range(len(dLen)):
        p = 1 / 2.0 * (dLen[i][0]+dLen[i][1]+dLen[i][2])
        S = math.sqrt(p * (p - dLen[i][0]) * (p - dLen[i][1]) * (p - dLen[i][2]))
        if max_S < S:
            max_S = S
    print '%.5f' % max_S
反正就是两点之间的距离和海伦公式求面积,哈哈!个人觉得这道题考的是你的耐心,因为点可能会很多。

当然前提你要知道如何根据点来求三角形面积。

4.

度度熊有一个N个数的数组,他想将数组从小到大 排好序,但是萌萌的度度熊只会下面这个操作:
任取数组中的一个数然后将它放置在数组的最后一个位置。
问最少操作多少次可以使得数组从小到大有序? 

输入描述:
首先输入一个正整数N,接下来的一行输入N个整数。(N <= 50, 每个数的绝对值小于等于1000)


输出描述:
输出一个整数表示最少的操作次数。

输入例子:
4
19 7 8 25

输出例子:
2

个人思路:

先看当时写的想法

找出 n-1 中最大的数,放到末尾去,count++,直到排序成功

以这个主思路去写,结果,嗯,我个人觉得只要不考虑时间问题,是没有问题的。因为测试时,30%case,让我检查时间

正确答案(本人 && 牛客网 id:古典文化):

n = int(raw_input())
arr = [int(i) for i in raw_input().strip().split()]
sort_arr = sorted(arr)
temp = arr[:]
count = 0
while arr != sort_arr:
    del temp[n-1]   # 删除最后一个
    max_temp = max(temp)    # 前 n-1 的最大值
    # 找出 max_temp 的位置
    for i in range(n):
        if arr[i] == max_temp:
            delete = i
            break   # 找到前 n-1 的最大值的小标了
    # 在原数组中删除,并加入到尾部
    del arr[delete]
    arr.append(max_temp)
    temp = arr[:]
    count += 1
print count
因为用到了 [:],解决了很多问题,因此把我的次品也搬上了。然后看看网上的正确答案

while True:
    try:
        num = int(raw_input())
        li = map(int, raw_input().strip().split())
        liSort = sorted(li)
        count = 0
        j = 0
        for i in range(num):
            if li[i] == liSort[j]:
                j = j + 1
            else:
                count = count + 1
        print count
         
    except:
        break
这个用了 map,之后,大家都一样,先把排序好的弄出来,下面是进行的比较

不过人家这里比较的是每位,而我是整个数组。这都可以吗。厉害。

5.

度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 '>' 和 '<' )使其成为一个合法的不等式数列。但是现在度度熊手中只有k个小于符号即('<'')和n-k-1个大于符号(即'>'),度度熊想知道对于1至n任意的排列中有多少个排列可以使用这些符号使其为合法的不等式数列。 

输入描述:
输入包括一行,包含两个整数n和k(k < n ≤ 1000)


输出描述:
输出满足条件的排列数,答案对2017取模。

输入例子:
5 2

输出例子:
66

个人思路:

是先找不能构成的排列组合吧,从例子来看不能构成的还是少
2 个 < ,2 个 >
72种排列,只有6个不能
12345
54321
小大排序可能不行

n 与 n + 1 的大小
n > n+1 = times 大于 '>' n-k-1 不合法
同理小于    
最后得出不合法的

难点:在于求所有组合的数组

然后最终还是败在了全排列这里,需要下去好好看: 

字符串的全排列和组合算法 - Hackbuteer1的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/hackbuteer1/article/details/7462447

正确答案(牛客网 id:jwx 另外一个 id 和此答案相同):

try:
        while True:
            line = raw_input()
            if line == "":
                break
            [n,k] = [int(item) for item in line.split(" ")]
            if k < 0 or k > n - 1:
                print(0)
            elif n == 1 or n == 2 or k == n - 1 or k == 0:
                print(1)
            else:
                prev = [0] * (k+1)
                prev[0] = 1
                prev[1] = 1
                curr = [0] * (k+1)
                for i in range(3,n+1):
                    for j in range(k+1):
                        if j == 0:
                            curr[j] = 1
                        elif j <= i - 2:
                            curr[j] = (j+1)*prev[j] + (i-j)*prev[j-1]
                            curr[j] = curr[j] % 2017
                        elif j == i - 1:
                            curr[j] = 1
                        else:
                            curr[j] = 0
                    prev = curr[:]
                print(curr[k])
except:
        pass
这个厉害了,没有全排列,而且还是一口气写完了!
先是特殊情况,然后两个 for 循环,curr 反正表示某一个 < or >,最后输出的还是 curr[k],厉害不。慢慢分析吧。


其实,读懂别人代码的能力,也是十分重要的。


以上是关于百度2017春招笔试真题编程题集合--Python的主要内容,如果未能解决你的问题,请参考以下文章

网易2017春招笔试真题编程题集合--Python

网易2017春招笔试真题编程题集合——分饼干

网易2017春招笔试真题编程题集合——集合

百度2017春招笔试真题编程题之有趣的排序

网易2017春招笔试真题编程题集合——消除重复元素

网易2017春招笔试真题编程题集合题解