2020阿里實習校招算法筆試題

使用Python2.7.3

題目1: 隊伍選擇

題目描述:現有n個人,要從這n個人中選任意數量的人組成一隻隊伍,再在這些人中選出一名隊長,求不同的方案對109+710^9+7取模的結果。如果兩個方案選取的人的集合不同或選出的隊長不同,則認爲這兩個方案是不同。
輸入描述

一行一個數字n。
1<=n<=1091<=n<=10^9

輸出描述

一行一個數字表示答案

示例1
輸入

2

輸出

4

說明

4種方案爲(1^)(\hat1)(2^)(\hat2)(1^,2)(\hat1,2)(1,2^)(1,\hat2),其中x^\hat x表示選取xx爲隊長。

思路
n=1,f(1) = C11C^1_1*1
n=2,f(2) = C21C^1_2*1 + C22C^2_2*2
n=3,f(3) = C31C^1_3*1 + C32C^2_3*2 + C33C^3_3*3
……
其中CnxC^x_n = n!(nx)!x!\frac{n!}{(n-x)!x!}

在計算f(n)時,需要計算排列組合,排列組合公式用到了階乘。如果空間複雜度要求不高,還可以將前面的結果都保存下來,這樣可以減少計算量。

代碼

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.fact_x = 0
        self.fact_n_x = 0

    def NumOfSquad(self, n):
        if n < 1 or n > 10**9:
            return 0
        sum = 0
        for i in range(1,n+1):
            sum += self.NumOfChoose(n,i) * i
        return sum%(10**9+7)
            
        
    def NumOfChoose(self, n, x):
        if x == 1:
            return n
        return int(self.factorial(n,x)/self.fact_n_x/self.fact_x)

    def factorial(self, n, x):
        if n == 1:
            return 1
        res = 1
        for i in range(1,n+1):
            res =((res%(10**9+7)) * (i%(10**9+7))) % (10**9+7)
            if i == x:
                self.fact_x = res
            if i == n-x:
                self.fact_n_x = res
        return res

if __name__ == "__main__":
    num = 10000
    solution = Solution1()
    
    import time
    start = time.clock()
    
    print(solution.NumOfSquad(num))
    
    end = time.clock()
    print(str(end-start))

輸出結果

20000
21.9018636

題目2:對稱飛行器

小強在玩一個走迷宮的遊戲,他操控的人物現在位於迷宮的起點,他的目標是儘快到達終點。
每一次他可以選擇花費一個時間單位向上或向下或向左或向右走一格,或是使用自己的對稱飛行器花費一個時間單位瞬移到關於當前自己點中心對稱的格子,且每一次移動的目的地不能存在障礙物。
具體來說,設當前迷宮有nm列,如果當前小強操控的人物位於點A(x,y)A(x,y),那麼關於點A中心對稱的格子B(x,y)B(x',y')滿足x+x=n+1x+x'=n+1y+y=m+1y+y'=m+1
需要注意的是,對稱飛行器最多使用5次。
輸入描述

第一行兩個空格分隔的正整數nm,分別代表迷宮的行數和列數。接下來n行每行一個長度爲m的字符串來描述這個迷宮。
其中
\cdot代表通路
#\#代表障礙
SS代表起點
EE代表終點
保證只有一個SS和一個EE
2<=n,m<=5002<=n,m<=500

輸出描述

僅一行一個整數表示從起點最小花費多少時間單位到達終點。如果無法到達終點,輸出-1。

示例1
輸入

4 4
#S\cdot \cdot
E#\cdot \cdot
#\cdot \cdot \cdot
\cdot \cdot \cdot \cdot

輸出

4

說明

一種可行的路徑是用對稱飛行器到達(4,3)再向上走一步,再向右走一步,然後後使用一次對稱飛行器到達終點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章