互联网笔试+网易2019暑期实习编程题+拼多多19校招

  • 语法错误总结
    • 牛客网的bug
    • 防止空行的循环读取输入
    • 字符串中的字符不能被 = 直接替换值
    • 如何遍历一个数字的所有位
    • 2列list排序,一列升序,一列降序
    • 如何求两个list/set的交集
  • 机器学习岗 牛牛找工作(动态规划)
  • 数对 (机器学习岗位的题,数字找规律题)
  • 被3整除(前端的题,类似于智力题,考找规律)
  • 安置路灯(贪心)
  • 2017年最大奇约数
  • 19年拼多多校招

语法错误总结

牛客网的bug

不知道为什么有的时候int()在牛客网python3.5.2的环境下就会报错,但是同样的代码放到python2.7.3里就不会报错。
而且python2.7.3可以接受print()输出

防止空行的循环读取输入

oneline=sys.stdin.readline().strip()
while not oneline:
    oneline=sys.stdin.readline().strip()

N,M=map(int,oneline.split())

字符串中的字符不能被 = 直接替换值

s='abcdef'
s[2]='g'
Traceback (most recent call last):
  File "D:\Software\Anaconda3-5.1.0\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "", line 1, in 
    s[2]='g'
TypeError: 'str' object does not support item assignment

想要解决这个问题,可以把str换成list,然后再对list的元素赋值

l=list(s)
l
Out[5]: ['a', 'b', 'c', 'd', 'e', 'f']
l[2]='g'
l
Out[9]: ['a', 'b', 'g', 'd', 'e', 'f']

如何遍历一个数字的所有位


num=123456
while (num):
    mod=int(num % 10)
    print("current last digit is",mod )
    num =int( num/10)
#当1/10=0,while(0)的时候,程序自然会结束

#输出如下:
current last digit is 6
current last digit is 5
current last digit is 4
current last digit is 3
current last digit is 2
current last digit is 1

2列list排序,一列升序,一列降序

mat=[[1,3],[2,5],[3,2],[4,9],[2,8],[1,5]]
print (mat)
#mat.sort(key=lambda x:[x[1],x[0]])
#[[3, 2], [1, 3], [1, 5], [2, 5], [2, 8], [4, 9]]
#以下两句效果一样
#mat.sort(key=lambda x:[x[1],x[0]],reverse=True)
#mat.sort(key=lambda x:(x[1],x[0]),reverse=True)
#[[4, 9], [2, 8], [2, 5], [1, 5], [1, 3], [3, 2]]
mat.sort(key=lambda x:(x[1],-x[0]))
#[[3, 2], [1, 3], [2, 5], [1, 5], [2, 8], [4, 9]]
#按第二列升序排序,如果第二列数值相同,按第一列降序排序

如何求两个list/set的交集

有现成的轮子,不用我自己造!set对象有intersection求交集函数

a=[1,2,4]
b=[2,3,4,9,11]
set(a).intersection(b)
Out[3]: {2, 4}
set(a).intersection(set(b))
Out[4]: {2, 4}
type(set(a).intersection(b))
Out[8]: set
type(set(a).intersection(set(b)))
Out[9]: set#输出默认为set
list(set(a).intersection(b))
Out[10]: [2, 4]#强制转换成list

机器学习岗 牛牛找工作(动态规划)

题目:
[编程题] 牛牛找工作
时间限制:2秒

空间限制:65536K

为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。
输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量N(N<=100000)和小伙伴的数量M(M<=100000)。
接下来的N行每行包含两个正整数,分别表示该项工作的难度Di(Di<=1000000000)和报酬Pi(Pi<=1000000000)。
接下来的一行包含M个正整数,分别表示M个小伙伴的能力值Ai(Ai<=1000000000)。
保证不存在两项工作的报酬相同。

输出描述:
对于每个小伙伴,在单独的一行输出一个正整数表示他能得到的最高报酬。一个工作可以被多个人选择。

输入例子1:
3 3
1 100
10 1000
1000000000 1001
9 10 1000000000

输出例子1:
100
1000
1001
我的思路:
法一(借鉴):用maplist存储工作能力和报酬的对应关系,不仅存储所有工作的,而且也存储每个小伙伴的工作能力和报酬(为0),这样在后面计算的时候不用两层for循环,而使用一层for循环就可以搞定,
因为不需要判断小伙伴的能力值和工作能力值的大小关系,只需要计算,到目前的能力值为止,所能获得的最大报酬数,有种dp的味道,用ma保存历史最大报酬数,然后再更新到maplist中即可。

我的解法:(这里包含了处理空行的代码,如果没有处理空行不能AC,很坑)

import  sys
import copy
oneline=sys.stdin.readline().strip()
while not oneline:
    oneline=sys.stdin.readline().strip()

N,M=map(int,oneline.split())
Diff=[]
maplist={}#maplist,字典形式的哈希表,记载的是到某工作难度为止,对应的最大报酬,有DP解法的思想
#因为工作难度在下文会按从小到大排列,所以说“到某工作难度为止”


while (N > 0):
    suboneline=sys.stdin.readline().strip()
    while not suboneline:
            suboneline=sys.stdin.readline().strip()
    D, P = map(int, suboneline.split())
    Diff.append(D)
    maplist[D]=P#job字典把每个工作的难度值和报酬以键值对形式存储,假设没有重复难度的工作
    N = N - 1


abiline = sys.stdin.readline().strip()
while not abiline:#防止空行
    abiline = sys.stdin.readline().strip()
FriendAbilist = list(map(int, abiline.split()))#读取小伙伴的能力值


for abi in FriendAbilist:#遍历要找工作的小伙伴的能力值
    Diff.append(abi)#把能力值添加到存放已经有的工作的难度值列表里
    if abi not in maplist.keys():#如果小伙伴的能力值还没被 job字典记录,则添加键值对 工作难度及其对应报酬为0
        maplist[abi]=0

Diff.sort()#对工作的难度排序(其中包括小伙伴的能力值)

maxpay = 0
for d in Diff:
    # 每次都更新当前能力值所对应的最大报酬,由于ma是保存的<=当前能力值所能获得的最大报酬,所以可行
    maxpay=max(maxpay,maplist.get(d))#有DP(动态规划)的思想
    maplist[d] =maxpay

for friendabi in FriendAbilist:
    #遍历小伙伴的能力值,从maplist哈希表中读取最大报酬
    print(maplist.get(friendabi))

复杂度分析:
O(2m)遍历小伙伴的能力值
+ O(m+n) 遍历排序后的Diff
+ 对Diff排序O(nlogn)

总的来说,比不用hashmap而是暴力求解的O(mn)的方法还是好多的
暴力求解的话O(mn)超时


注:本文解法思路借鉴自https://www.cnblogs.com/cing/p/8674813.html



数对 (机器学习岗位的题,数字找规律题)

[编程题] 数对
时间限制:1秒
空间限制:32768K
牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。
但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。
牛牛希望你能帮他计算一共有多少个可能的数对。

输入描述:
输入包括两个正整数n,k(1 <= n <= 10^5, 0 <= k <= n - 1)。

输出描述:
对于每个测试用例, 输出一个正整数表示可能的数对数量。

输入例子1:
5 2

输出例子1:
7

例子说明1:
满足条件的数对有(2,3),(2,4),(2,5),(3,4),(3,5),(4,5),(5,3)

import sys
n,k=map(int,sys.stdin.readline().strip().split())
res=0
if k==0:
        print(n*n)
else:
        for y in range(k+1,n+1):
            res=res+int(n/y)*(y-k)+max(0,n%y-k+1)
        print(res)

我的解法借鉴自此图:
互联网笔试+网易2019暑期实习编程题+拼多多19校招_第1张图片

被3整除(前端的题,类似于智力题,考找规律)

时间限制:1秒
空间限制:32768K
小Q得到一个神奇的数列: 1, 12, 123,…12345678910,1234567891011…。
并且小Q对于能否被3整除这个性质很感兴趣。
小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。

输入描述:
输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。

输出描述:
输出一个整数, 表示区间内能被3整除的数字个数。

输入例子1:
2 5

输出例子1:
3

例子说明1:
12, 123, 1234, 12345…
其中12, 123, 12345能被3整除。
思路:
这道题是有规律的


#include
using namespace std;

int main(){
    int left, right;
    int result = 0;

    cin >> left >> right;
    for(int i=left; i<=right; ++i){
        switch(i%3){
            case 1: ;break;
            case 2: ++result;break;
            case 0: ++result;break;
        }
    }
    cout << result << endl;
}
//同样解法python就不能AC
#AC了70%,因为超时了
import  sys
l,r=map(int,sys.stdin.readline().strip().split())

cnt=0
for i in range(l-1,r):
    if i%3!=0:
        cnt=cnt+1

print(cnt)
序号 序号除以3的余数 数字
1 1 1
2 2 12
3 0 123
4 1 1234
5 2 12345
6 0 123456
7 1 1234567
8 2 12345678
9 0 123456789
10 1 12345678910
11 2 1234567891011
12 0 123456789101112
#这还是python2.7的环境,不知道为什么放到python3.5的环境里就有语法错误了
import sys
l, r = map(int, sys.stdin.readline().strip().split())
lmod = l % 3
rmod = r % 3
if (lmod == 0 and (rmod == 0 or rmod == 1)) or (lmod == 2 and rmod == 2) or (lmod == 1 and rmod == 2):
    cnt = int((r - l) / 3) * 2 + 1
if (lmod == 0 and rmod == 2):
    cnt = int((r - l) / 3) * 2 + 2
if (lmod == 1 and rmod == 0) or (lmod == 2 and rmod == 1):
    cnt = int((r - l + 1) / 3) * 2
if (lmod == 1 and rmod == 1):
    cnt = int((r - l) / 3) * 2
if (lmod == 2 and rmod == 0):
    cnt = int((r - l + 2) / 3) * 2
print cnt

安置路灯(贪心)

时间限制:1秒
空间限制:32768K
小Q正在给一条长度为n的道路设计路灯安置方案。
为了让问题更简单,小Q把道路视为n个方格,需要照亮的地方用’.’表示, 不需要照亮的障碍物格子用’X’表示。
小Q现在要在道路上设置一些路灯, 对于安置在pos位置的路灯, 这盏路灯可以照亮pos - 1, pos, pos + 1这三个位置。
小Q希望能安置尽量少的路灯照亮所有’.’区域, 希望你能帮他计算一下最少需要多少盏路灯。

输入描述:
输入的第一行包含一个正整数t(1 <= t <= 1000), 表示测试用例数
接下来每两行一个测试数据, 第一行一个正整数n(1 <= n <= 1000),表示道路的长度。
第二行一个字符串s表示道路的构造,只包含’.’和’X’。

输出描述:
对于每个测试用例, 输出一个正整数表示最少需要多少盏路灯。

输入例子1:
2
3
.X.
11
…XX….XX

输出例子1:
1
3

解题思路:
重点在于读题,意识到:
1 X的地方不需要被照亮,但是也能放路灯,也能被照亮
2 明确 一盏路灯最多照亮三个位置
3 我们始终保证需要照亮的地方必须照亮即可
从一个给定的字符串,我们从头开始遍历,找到第一个需要照亮的地方,先不放置路灯灯,考虑从这里开始的连续三个位置的情况
可能的情况有 … .x. ..x .xx 但是其实都只是需要一盏路灯,隔开三个位置后,我们再找到余下的第一个.的位置(我理解为 永远都放在三个的中间就行了)
做如上的同样处理
遍历完毕后,得出结果

#Python3.5.2
import sys
casecnt=int(sys.stdin.readline().strip())
while(casecnt>0):
    lightcnt = 0
    casecnt=casecnt-1
    length=int(sys.stdin.readline().strip())
    road=sys.stdin.readline().strip()
    road=list(road)
    i=0
    while (iif road[i]=='.':#遇到. 路灯数+1 且 往后移三个位置
            lightcnt=lightcnt+1
            i=i+3
        elif road[i]=='X':#遇到X 往后移一个位置
            i=i+1
    print(lightcnt)

2017年最大奇约数

我的解法只AC了40%,超时了

import  sys

N=int(sys.stdin.readline().strip())
def findodd(num):
    mod=0
    while (mod==0):
        mod=int(num % 2)
        #print("mod is",mod)
        if mod!=0:
            odd=num
            #print("odd is",odd)
        num =int( num/2)
        #print("num is",num )
    return  odd

result=0
for i in range(1,N+1):
    result=result+findodd(i)

print(result)

然而, N的取值范围时10^10,所以O(n)的算法是超时的。

考虑优化,设sum(i) = f(1) + f(2) + … + f(i);

求sum(i)的过程中,对于f(i), i 为奇数可以直接求,就是 i 本身。

问题就是求所有f(i), i为偶数的和。

因为要求的是最大奇约数,所以f(2k) = f(k),所以f(2) + f(4) + … + f(2k) = f(1) + f(2) + … + f(k);

所以

sum(i) = sum (i / 2) + 1 + 3 + … + i - 1 (i 为偶数)

      =  sum (i - 1) + i (i 为奇数)

时间复杂度O(logn),可以解决。
正确解法(参考https://www.cnblogs.com/wangxiaobao/p/5866351.html)

import  sys

N=int(sys.stdin.readline().strip())

def findsum(N):
    if(N==1):
        return 1
    if N%2==0:
        return  findsum(N/2)+N*N/4
    else:
        return  findsum(N-1)+N

print(findsum(N))

19年拼多多校招

题目:题目1:字符串矩形输出
思路:计算出每行长度,然后分四次将字符加到每条边上,注意str.size()/4+1等于矩形边长。
我自己AC100%的,花了半个小时吧

import sys
import numpy as np
if __name__ == "__main__":
    # 读取第一行的n
    s = sys.stdin.readline().strip()
    K=int(len(s)/4)
    bianlen=K+1
    mat=[[" " for col in range(0,bianlen)] for row in range(0,bianlen)]
    #print (mat)
    #上边
    for col in range(bianlen):
        mat[0][col]=s[col]
    #右边
    for row in range(bianlen):
        mat[row][K]=s[K+row]

    #下边
    for col in range(bianlen):
        mat[K][col]=s[K-2*K-col]

    #左边
    for row in range(1,bianlen):
        mat[row][0]=s[4*K-row]
    #print (mat)

    for i in range(0,bianlen):
        output=""
        outputlist=[]
        for j in range(0,bianlen):
            outputlist.append(mat[i][j])
        print(output.join(outputlist))

题目3:最亲密的非朋友
思路:将输入存储到n*n的数组中,设要求的是i,将i行循环一遍,将每个和i不是朋友的取出来,与i的朋友进行比较,然后找出相似性最大的。
输入的时候,用到getline,要先getline一次,才能正常输入
AC了65%

import sys

if __name__ == "__main__":
    # 读取第一行的n
    n, k = map(int,sys.stdin.readline().strip().split())
    # 读取第一行的n
    fr=[]
    for i in range(n):
        # 读取每一行
        line = sys.stdin.readline().strip()
        # 把每一行的数字分隔后转化成int列表
        values = list(map(int, line.split()))
        fr.append(values)
    myself=fr[k]
    result=[]
    for num in range(0,n):
        if (num not in myself) and num!=k:
            length=len(fr[num])
            cnt=0
            for i in range(length):
                #print("now",fr[num][i])
                if fr[num][i] in myself:
                    #print("T")
                    cnt=cnt+1#不用这么费劲求交集,set对象有intersection()函数求交集
            result.append([num,cnt])
    print("now result is",result)
    if len(result)==0:
        print(-1)
    else:
        result.sort(key=lambda x: x[1],reverse=False)
        print(result[len(result)-1][0])

以上答案AC了65%,但不符合如果两个人与被查询的用户拥有相同数量的好友,则返回编号较小的人
修改为以下就符合了,但不知会AC多少,因为交卷了

result.sort(key=lambda x: (x[1],-x[0]))

看到一个大佬晒的100%的答案,其实思路和我是一样的

#coding=utf-8
import sys
def solution(links, n2):
    a = links[n2]
    result = 0
    for i in range(len(links)):
        if i == n2:
            continue
        else:
            b = links[i]
            intersection = list(set(a).intersection(set(b)))
            if i not in a:
                result = max(result, len(intersection))
    if result == 0:
        return -1 
    for i in range(len(links)):
        if i == n2:
            continue
        else:
            b = links[i]
            intersection = list(set(a).intersection(set(b)))
            if i not in a and len(intersection) == result:
                return i


if __name__ == "__main__":
    # 读取第一行的n
    ns = sys.stdin.readline().strip().split()
    n1 = int(ns[0])
    n2 = int(ns[1])
    links = []
    for i in range(n1):
        line = sys.stdin.readline().strip()
        values = map(int, line.split())
        links.append([i for i in values])
    print(solution(links, n2))

你可能感兴趣的:(算法)