Python算法學習: 競碼編程-藍橋杯模擬賽3題解

A. 試題A:生存還是毀滅,這是一個問題 7’

描述
對於給定的文章,求出出現頻率最高的字母。

對於字母的出現頻率,我們定義爲:該字母在整個文章中出現的次數。

例如:“To be or not to be, that is the question!”

出現頻率最高的字母是:t,總共出現了77次。

對於以下莎士比亞的《哈姆雷特》經典片段,你能幫JM找到出現頻率最高的字母出現的次數嗎?

輸出出現頻率最高的字母出現的次數。

注意:字母不區分大小寫。

思路:

這裏我將a-z A-Z的ascii 編碼作爲篩選點, 將所有的字母傳入新列表然後尋找
str = ''' To be, or not to be: that is the question,
Whether it's nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles,
And by opposing end them. To die,to sleep;
No more; and by a sleep to say we end
The heartache, and the thousand natural shocks
That flesh is heir to, it's a consummation
Devoutly to be wished. To die, to sleep.
To sleep, perchance to dream: ay, there's the rub;
For in that sleep of death what dreams may come
When we have shuffled off this mortal coil,
Must give us pause. There's the respect
That makes calamity of so long life;
For who would bear the whips and scorns of time,
The oppressor's wrong, the proud man's contumely,
The pangs of despised love, the law's delay,
The insolence of office, and the spurns
That patient merit of the unworthy takes,
When he himself might his quietus make
With a bare bodkin? Who would fardels bear,
To grunt and sweat under a weary life,
But that the dread of something after death,
The undiscovered country from whose bourn
No traveller returns, puzzles the will,
And makes us rather bear those ills we have
Than fly to others that we know not of?
Thus conscience does make cowards of us all,
And thus the native hue of resolution
Is sicklied or with the pale cast of thought,
And enterprises of great pith and moment
With this regard their currents turn awry
And lose the name of action.'''
strq = ""
tmp = 0
ans = 0
# 97 122 65 90
for i in str:
    if 65<=ord(i)<=90 or 97<=ord(i)<=122:
        strq += i.lower()
for i in strq:
    tmp = strq.count(i)
    if tmp>ans:
        ans = tmp
print(ans)

B. 試題B:小小神槍手 開局98K 8’

描述
JM是一個吃雞玩家,開局98K,人物描邊大師。

已知JM的初始射擊命中率爲75%75%。如果JM一擊未中,則會由於種種原因(心理壓力)導致JM的命中率在上一槍的命中率基礎上,減低10%10%。

例如:第一槍的命中率爲75%75%,則第二槍的命中率爲75% * 90%75%∗90%,第三槍的命中率爲75% * 90% * 90%75%∗90%∗90%,以此類推。

當然,當命中率低於50%50%的時候,JM則會放棄射擊。

現在,JM想知道,他擊中敵人的期望次數是多少? 保留66位小數。

注意:

1、射擊命中則停止射擊
2、放棄射擊則不統計次數。

思路:
在這裏插入圖片描述
這裏就是很簡單的數學期望問題

n1 = 0.75
n2 = 0.675000
n3 = 0.607500
n4 = 0.546750
ans = n1 + 2*((1-n1)*n2) + 3*((1-n1)*(1-n2)*n3) + 4*((1-n1)*(1-n2)*(1-n3)*n4)
print(ans)

C. 試題C:關雲長單刀會金蓮,賈寶玉三打白骨精 10’

描述
三國在國,治國,興國,安國,喪國。

水滸在氣,勇氣,義氣,豪氣,霸氣。

紅樓在情,親情,愛情,宦情,民情。

西遊在趣,情趣,遊曲,野趣,妖趣。

由於四大名著的魅力實在是太大了,JM決定把整個3月空出來,再次品味一下這四大名著。

JM 決定在3月的31天中挑出連續的4天學習《水滸傳》,連續的3天看《西遊記》,連續的5天看《三國演義》,連續的3天看《紅樓夢》。注意:同一天不可能看兩本名著。

現在,JM同學想知道,他有多少種時間安排方法,能夠滿足他學習的需求。

例如:

第1-5天看《三國演義》,第6-8天看《西遊記》,第9-11天看《紅樓夢》,第12-15天看《水滸傳》,這是一種合法的方案
第2-5天看《水滸傳》,第10-14天看《三國演義》,第17-19天看《西遊記》,第29-31天看《紅樓夢》,這也是一種合法的方案。

思路:

我們通過枚舉每一個名著的開始閱讀時間,然後判斷這種可能方案,滿不滿足要求。
也就是每一本名著讀書的那天,不能讀其他的。
我們可以用一個變量 vis,記錄每一天是否已經讀過了
'''
我們通過枚舉每一個名著的開始閱讀時間,然後判斷這種可能方案,滿不滿足要求。也就是每一本名著讀書的那天,不能讀其他的。
我們可以用一個變量 vis,記錄每一天是否已經讀過了
'''

def is_True(a,b,c,d):
    vis = [0 for _ in range(32)]
    for i in range(4):
        vis[a+i] = 1
    for i in range(3):
        if vis[b+i] != 1:
            vis[b+i] = 1
        else:
            return False
    for i in range(5):
        if vis[c + i] != 1:
            vis[c + i] = 1
        else:
            return False
    for i in range(3):
        if vis[d + i] != 1:
            vis[d + i] = 1
        else:
            return False
    return True
if __name__ == '__main__':
    # a = 《水滸傳》 4天
    # b = 《西遊記》 3天
    # c = 《三國演義》 5天
    # d = 《紅樓夢》 3天
    ans = 0
    for a in range(1, 29): # 第28天爲最晚讀書日期
        for b in range(1, 30):# 第29天爲最晚讀書日期
            for c in range(1, 28):# 第27天爲最晚讀書日期
                for d in range(1, 30):# 第28天爲最晚讀書日期
                    if is_True(a,b,c,d):
                        ans += 1

    print(ans)

D. 試題D:抽刀斷水水更流,舉杯銷愁愁更愁 10’

憂鬱的JM,借酒消愁。略微喝醉的他,和下酒花生聊起了天。

JM:“你知道質數是什麼嗎?”

花生:“…”

JM:“質數是指在大於11的自然數中,除了11和它本身以外不再有其他因數的自然數。”

花生:“…”

JM:“現在我有一個質數集合{3, 5, 7, 11, 13, 19, 23, 29, 31, 37, 41, 53, 59, 61, 67, 71, 97, 101, 127, 197, 211, 431}3,5,7,11,13,19,23,29,31,37,41,53,59,61,67,71,97,101,127,197,211,431,你可以從中挑出任意多個(0-12個)不同的數出來構成一個新數(取出數的和)”

JM:“構成的新數從小到大依次爲:0, 3, 5, 7, 8, 10, 11, 12, 13…,0,3,5,7,8,10,11,12,13…,你知道[0, 1694][0,1694]中有多少個數是沒法構成的嗎?”
花生:”…“

JM:“例如:1,2,4…1,2,4…均是不能夠從質數集合中挑數構成”

你來幫幫花生吧~

思路:

這道題乍一看很簡單,但是寫代碼的時候思路總是理不清楚
上網查了一下發現這道題可以用二進制枚舉的方法
總共 22 個數,選擇其中的 0 -12 個數,加上來組成一個新數。

我們可以用二進制枚舉,對於 22 個數,每一個數,只有拿或不拿兩種情況,也就是 0 或者 1。所以總共有 2 ^ 22 約等於 4e6。不會超時。

因爲我們用二進制枚舉,每一位對應這個數要不要取,如果取,那就累和。還要注意,最後只能取 12 個,所以我們要判斷,這種取法中 1 的個數,如果是 >12 ,那這種方案不成立。

然後算出所有情況的數,用 set 統計(可能有重複的,去重)。

最後答案是問,無法構成的個數,因此答案是 : 總數(1695) - set 中的數(可以構成了這麼多數)

具體可以參考我的這篇博客:Python算法學習:全排列的回溯實現與二進制枚舉

nums = [3,5,7,11,13,19,23,29,31,37,41,53,59,61,67,71,97,101,127,197,211,431]
ans = [] #存放所有答案

for i in range(1<<22): # 2^22-1種情況(這裏是取0或者取22個數的全部可能情況)
    cnt = 0 # 計數 控制取數不超過12
    res = 0 # 結果
    tmp = i
    for j in range(22): # 查看22位中都有哪一位放了數字,即是1
        if (tmp >> j) & 1: # 如果第j位是1,則符合
            cnt += 1
            res += nums[j]
        if cnt <= 12:    # 不超過12位
            ans.append(res)
ans = set(ans)         # 使用集合的特性,去重
cnt = 1695
print(ans)
print(cnt - len(ans))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章