语法错误总结
牛客网的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 "<ipython-input-3-de2b46919b4e>", line 1, in <module>
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)
我的解法借鉴自此图:
被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<iostream>
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 (i<length):
if 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))