0408微衆筆試覆盤

博主0408的時候參加了微衆筆試,感覺題目不難但是沒有全AC。下來複盤的時候感覺自己考試的時候可能是腦子進水了,很多顯而易見的情況都沒考慮到。果然這段時間沉迷小說遊戲綜藝讓腦子也變得安逸了。閒話不再續,下面正式覆盤。

1 分禮物

有n位小朋友去小明家裏拜年,小明準備了m份禮物。小明想把所有禮物平均分給每個小朋友,每個小朋友得到相同個數的禮物。但是m未必能被n整除,小明可以使用以下兩種操作任意多次(兩種操作可以同時使用)。
1、 給其中一個小朋友發紅包,收到紅包的小朋友會離開小明家。每個紅包需要花費a元。
2、 購買一個新禮物,每個禮物價值爲b元。
問小明最少花費多少元,才能使得所有禮物可以被剩下的小朋友平分。
第一行輸入四個整數n,m,a,b(1≤n,m,a,b≤100)。
輸出最少花費。
輸入樣例1
7 5 10 100
20
輸入樣例2
2 2 10 10
輸出樣例2
0
輸入樣例3
3 1 10 10
輸出樣例3
20
樣例解釋
樣例一發兩個紅包。樣例二不需要任何操作。樣例三買兩個新禮物,或者發兩個紅包,或者發一個紅包買一個新禮物。

由於被測試用例糊住了,先入爲主的認爲送禮物的數量等於送走的朋友數,實際上這種等式關係只有m<n或其他特定情況才成立。也是沾了測試用例的光,這種想法居然也A了91。
此題的point恰恰在於送禮物的數量不一定等於送走的朋友數,假設送走了ii個小朋友,買了kk個新禮物,題目要求(m+k)%(ni)==0(m+k)\%(n-i)==0,且ai+kbai+kb最小。可以遍歷做。

def test(n,m,a,b):
    min = None
    if m%n == 0:
        return 0
    else:
        # 假設紅包送走i個小朋友
        for i in range(n):
            # 剩下n-i個小朋友中沒有禮物的小朋友
            if n==i:
                res = n*a
            else:
                if m%(n-i)==0:
                    res = i*a
                else:
                    tmp = (n-i) - m%(n-i)
                    res = tmp * b + i*a
            if not min or min>res:
                min = res
        return min

2 迴文遊戲

Cassidy和Eleanore是一對好朋友,她們經常會一起玩遊戲。某一天她們玩了一個迴文遊戲。遊戲規則是這樣的:給出一個僅包含小寫字母的字符串S,在每一個人的回合中,她們會進行兩個操作:
1 嘗試重新排列這個字符串,如果可以把這個字符串排列成迴文字符串,則立即獲勝。
2 否則,她們必須刪掉字符串中的一個字符。
已知,Cassidy先手,在兩個人都採取最佳策略的情況下,誰可以獲勝。
輸入第一行僅包含一個正整數t,表示數據組數,(t<=10)
接下來有t行,每行有一個字符串S,表示一組測試數據。(|S|<=1000)
對於每組數據輸出一行,如果Cassidy獲勝,則輸出Cassidy,否則輸出Eleanore
輸入樣例
2
aba
ab
輸出樣例
Cassidy
Eleanore

這個題還是比較友好,全ac了。一個字符串若能構成迴文串,串中計數爲奇數的字符個數不能大於1,否則無法構成字符串。最優策略就是,先檢查字符串,若能構成迴文串,勝利;若不能,優先將串中計數爲偶數的字符刪掉一個。

    def createDic(s):
        dic = {}
        for i in s:
            if i not in dic:
                dic[i] = 1
            else:
                dic[i] += 1
        return dic

    def testPalin(dic):
        odd_count = 0
        even_count = 0
        for key in dic:
            if dic[key] % 2 == 1:
                odd_count += 1
            else:
                even_count += 1
        if odd_count > 1:
            return False
        else:
            return True

    def delString(dic):
        # 如果存在偶數,將偶數刪成奇數,使奇數儘可能多
        flag = False
        for key in dic:
            if dic[key] > 0 and dic[key]%2 == 0:
                dic[key] -= 1
                flag = True
                break
        # 如果刪除失敗,沒有偶數字符;只能刪除奇數字符
        if not flag:
            for key in dic:
                if dic[key] > 0 and dic[key] % 2 == 1:
                    dic[key] -= 1
                    break


    def test(s):
        # s:字符串
        dic = createDic(s)
        count = 0
        while True:
            if testPalin(dic):
                if count%2==0:
                    return 'Cassidy'
                else:
                    return 'Eleanore'
            else:
                delString(dic)
            count += 1

3 抽卡遊戲

抽卡是一類類似於博弈的遊戲。現在有一種抽卡方式,描述如下:
初始你只有一次抽卡機會。每次抽卡浪費一次抽卡機會,獲得一張卡片。這張卡片上有兩個數字,第一個數字代表你能獲得的錢,第二個數字代表你能獲得的額外抽卡次數。額外的抽卡次數是可以累計的。
現在,你知道了卡片的數量,所有的卡片上的數字,以及所有卡片的順序。你只需要安排一種抽卡順序,使得你能獲得錢數最多。
輸入:
第一個行一個數n,代表卡片的數量。 接下來n行,每行用兩個數ai,bi描述一張卡片。ai表示抽這張卡能獲得的錢數,bi表示抽這張卡能獲得的額外抽卡次數。
輸出:
一行一個數,代表你能獲得的最多錢數。
輸入樣例
5
0 2
1 1
1 0
1 0
2 0
輸出樣例
4
對於100%的數據,0≤a_i,b_i≤1000,1≤n≤1000。樣例解釋:按順序抽第2,1,5,4張卡

此題我的想法是先把有抽卡次數的卡抽了,再按照錢數大小抽卡。看了牛客大家的思路都是類似的,但是我只ac了72。仔細比照了一下代碼,實在是發現不出來問題。
不過:其實可以先把有抽卡次數的全部先消耗掉(即有抽卡次數的卡不參與排序),只排序無抽卡次數,有錢數的卡。
後來發現可能不是邏輯的問題,而是while循環的判斷有誤,可能還有count值但是卡已經抽完了,這個時候我的代碼會報邊界錯誤。果然筆試時不能再主文件寫try…except,否則有錯誤也不會報出來。

def test(arr):
    arr = sorted(arr,key=lambda x:(x[1],x[0]),reverse=True)
    # arr = sorted(arr, key=lambda x: (-x[0], x[1]))
    print(arr)
    count = 1
    money = 0
    for i in range(len(arr)):
        if count == 0: break
        tmp =arr[i]
        count = count - 1 + tmp[1]
        money = money + tmp[0]
    return money
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章