mark下遇到的笔试题吧
招行算法:
同学遇到的题,笔试后交流了下思路,由于a范围比较小,所以可以暴力(搜索剪枝)加用集合和字典优化。复杂度大概O(n*logn)
有n种不同的化学试剂。第i种有ai升。每次实验都要把所有的化学试剂混在一起,但是这些试剂的量一定要相等。所以现在的首要任务是把这些化学试剂的量弄成相等。
有两种操作:
· 把第i种的量翻倍,即第i种的量变成2ai。
· 把第i种的量减半,除的时候向下取整,即把第i种的量变成 ⌊ ai2 ⌋ 。
现在所有的化学试剂的量已知,问最少要变换多少次,这些化学试剂的量才会相等。
Input
单组测试数据。
第一行有一个整数n (1 ≤ n ≤ 10^5),表示化学物品的数量。
第二行有n个以空格分开的整数ai (1 ≤ ai ≤ 10^5),表示第i种化学试剂的量。
Output
输出一个数字,表示最少的变化次数。
Input示例
3
4 8 2
Output示例
from collections import defaultdict
n=input()
l=list(map(int,input().split()))
def slove(l):
if len(l)<=1:
return 0
ans=defaultdict(int)
p=set(range(10001))
for i in l:
q=[(i,0)]
visted=set()
while q:
k,l=q.pop()
if k>=1 and k<=10000 and k not in visted:
ans[k]+=l
visted.add(k)
q.append((k<<1,l+1))
q.append((k>>1,l+1))
p=p&visted
res=100000000086
for k in p:
res=min(res,ans[k])
return res
print(slove(l))
阿里机器学习算法
由于数据不大,所以两道分析出公式后,就可以模拟。
第一题,两个人分奖金,给一个概率的序列分别[p0,p1,p2,p3…pN]依次表示A,B取得奖金的概率,序列到底后从p0开始(假如是奇数的话从p1开始),但是超过100轮的话,则结束。求A分得奖金概率,保留4位小数。
N=int(input())
p=[0]
for i in range(N):
p.append(float(input()))
def sovle(N,p):
ans=0
if N%2==1:
k=100//N+1
p=p+p[2:]*k
else:
k=100//N+1
p=p+p[1:]*k
ans=0
for i in range(1,101):
if i%2==1:
midans=p[i]
for k in range(0,i):
midans*=(1-p[k])
ans+=midans
return round(ans,4)
print(sovle(N,p))
第二题
M个鱼丸,N个肉丸,K个婉,(0<M,N<=50,K>0), 每个碗最多装50个丸子,鱼丸肉丸不混在一个碗,不区分碗,求装法。空碗不计。
m=int(input())
n=int(input())
k=int(input())
mod=10000
def C(a,b):
ans=1
for i in range(a-b+1,a+1):
ans*=i
for j in range(1,b+1):
ans=ans/j
return ans%mod
def sovle(m,n,k):
k=min(k,m+n)
if k<=1:
return 0
pm=[0]*(m+1)
pn=[0]*(n+1)
res=0
for j in range(1,m):
res+=C(m,j)
pm[j]=res
res=0
for j in range(1,n):
res+=C(n,j)
pn[j]=res
ans=0
for i in range(1,k):
ans+=pm(i)*pn(k-i)
ans=ans%mod
return ans
print(sovle(m,n,k))
考试的时候没A,只通过部分,感觉是考虑的特殊情况不全面。