某互联网公司2019年实习春招算法机器学习笔试编程题及解答

编程题有两道,我在这里写出自己的基础解法以供参考,有优化的地方的话请指正。

第一道:

班上同学聚餐吃火锅,一锅煮了的M(1<=M<=50)个鱼丸和N(1<=N<=50)个肉丸,现欲将M个鱼丸和N个肉丸分到K(1<=K<=50)个碗中,允许有空碗,鱼丸和肉丸不允许混在同一个碗里,问共有多少种装法。假设碗足够大,能装50个鱼丸或者50个肉丸,碗之间也没有区别,因此当N=M=1,K=3时,只有一种解法,因为(1,1,0)(1,0,1)(0,1,1)被看做是同一种装法。

输入:

输入数据包含三行,每行一个整数,分别是M、N、K(1<=M,N,K<=50)

输出:

一个整数,单独一行,输出共有多少种装法,要求输出结果对10000取模,例如,计算出共有123456中装法,则输出3456

解题思路:

这是一个整数拆分问题:

首先考虑对于K个碗有K_i个碗占满,2<=K_i<=K;

然后考虑对于K_i个占满的碗,将K_i拆分成两个数字K_1和K_2,表示M占的和N占的;如果K_1和K_2不相等,则也要考虑M占K_2个和N占K_1个的情况

接着考虑对于M个碗占K_1个碗的情况,也就是求将M拆分成K_1个数的情况,N也一样

最后将K_i对应的所有情况求和

代码如下:

import sys
def getSplitNumber(n,k):#将n划分为k个数,k个数里面可以有相同的数,有多少种不同的划分方法
    #print("(n,k)=",(n,k))
    if k==1:
        return 1
    elif k>n or n<1:
        return 0
    else:
        return getSplitNumber(n-1,k-1)+getSplitNumber(n-k,k)
M=int(sys.stdin.readline().strip())
N=int(sys.stdin.readline().strip())
k=int(sys.stdin.readline().strip())
if k==1:
    Result=0
elif k==2:
    Result=1
else:
    Result=0
    for k_i in range(2,k+1):#如果碗的个数大于2,则分别遍历有k_i个碗被占满的情况(2<=k_i<=k)
        #print("k_i=",k_i)
        if k_i==2:
            Result+=1
        else:
            # 因为有两种丸子,所以将占满的碗分成两种,鱼丸占和肉丸占,比如占满的碗的个数为5,则可以分为1+4,2+3两种占用方式,对于占用方式1+4来说也有两种,肉丸占1鱼丸占4和肉丸占4鱼丸占1

            for k_1 in range(1,int(k_i/2)+1):
                k_2=k_i-k_1
                #print("(k_1,k_2)=",(k_1,k_2))
                if k_1==k_2:#如果k_1和k_2相等,说明鱼丸和肉丸占碗的数量一样,只有一种情况
                    Result += getSplitNumber(M, k_1) * getSplitNumber(N, k_2)
                else:
                    #假如这里是鱼丸占k_1个,肉丸占k_2个碗,也就是求将鱼丸的个数M拆分成k_1个数,肉丸的个数拆分成k_2个数的情况
                    Result+=getSplitNumber(M,k_1)*getSplitNumber(N, k_2)
                    Result += getSplitNumber(M, k_2)*getSplitNumber(N, k_1)
Result=Result%10000
sys.stdout.write("%d"%Result)

第二道:

小明,小华是校内公认的数据算法大牛。两人组队先后参加了阿里云天池大赛多项奖金赛事,多次获奖, 小明是其中的队长。最近的一次工业数据智能竞赛中,两人又斩获季军,获得奖金1万元。
作为算法大牛,两人竞赛奖金分配也有独特方式,由两人共同编写的一个程序来决定奖金的归属。每次获奖后,这个程序首先会随机产生若干0-1之间的实数{p_1,p_2,...,p_n}。然后从小明开始,第一轮以p_1的概率将奖金全部分配给小明,第二轮以p_2的概率将奖金全部分配给小华,这样交替地小明、小华以p_i的概率获得奖金的全部,一旦奖金被分配, 则程序终止,如果n轮之后奖金依然没发出,则从从p_1开始继续重复(这里需要注意,如果n是奇数,则第二次从p_1开始的时候,这一轮是以p_1的概率分配给小华) ;自到100轮,如果奖金还未被分配,程序终止,两人约定通过支付宝将奖金捐出去。

输入:

输人数据包念N+1行,

第一行包含一个整数N
接下来N行,每行一个0-1之间的实数, 从p_1到p_N

输出:
单独一行,输出一个小教,表示小明最终获得奖金的概率,结果四舍五入, 小数点后严格保留4位(这里需要注意,如果结果为0.5,则输出0.5000)

解析有时间再添加

代码如下:

import sys
N=int(sys.stdin.readline().strip())
PList=list(map(float,sys.stdin.readline().strip().split()))
PMin=0
AllP=1
for i in range(100):
    j=i%N
    if i%2==0:
        PMin+=AllP*PList[j]
    AllP=AllP-AllP*PList[j]
#print("%.4f"%PMin)
sys.stdout.write("%.4f"%PMin)

整数划分问题参考网址:

https://blog.csdn.net/m0_38013346/article/details/78037208?utm_source=blogxgwz1

http://www.cnblogs.com/xingluzhe/archive/2009/09/01/1557844.html

猜你喜欢

转载自blog.csdn.net/skj1995/article/details/89280724
今日推荐