Python算法學習: 藍橋杯官方練習系統VIP題庫真題代碼講解(持續更新)

全部代碼我全部託管到我的GitHub上了,喜歡的麻煩點個關注和star吧😀

藍橋杯官網VIP試題與歷屆真題代碼Python實現與講解
在這裏插入圖片描述

文章目錄

試題 入門訓練 Fibonacci數列

資源限制
時間限制:1.0s   內存限制:256.0MB
問題描述
Fibonacci數列的遞推公式爲:Fn=Fn-1+Fn-2,其中F1=F2=1。

當n比較大時,Fn也非常大,現在我們想知道,Fn除以10007的餘數是多少。

輸入格式
輸入包含一個整數n。
輸出格式
輸出一行,包含一個整數,表示Fn除以10007的餘數。
說明:在本題中,答案是要求Fn除以10007的餘數,因此我們只要能算出這個餘數即可,而不需要先計算出Fn的準確值,再將計算的結果除以10007取餘數,直接計算餘數往往比先算出原數再取餘簡單。

樣例輸入
10
樣例輸出
55
樣例輸入
22
樣例輸出
7704
數據規模與約定
1 <= n <= 1,000,000

代碼示例:

n=int(input())
f1=f2=f3=1
if n == 1 or n == 2:
    print(1)
elif n > 2:
    for i in range(3,n+1):
        f3 = (f1 + f2) % 10007
        f1 = f2
        f2 = f3
    print(f3)
    

試題 入門訓練 圓的面積

資源限制
時間限制:1.0s   內存限制:256.0MB
問題描述
給定圓的半徑r,求圓的面積。
輸入格式
輸入包含一個整數r,表示圓的半徑。
輸出格式
輸出一行,包含一個實數,四捨五入保留小數點後7位,表示圓的面積。
說明:在本題中,輸入是一個整數,但是輸出是一個實數。

對於實數輸出的問題,請一定看清楚實數輸出的要求,比如本題中要求保留小數點後7位,則你的程序必須嚴格的輸出7位小數,輸出過多或者過少的小數位數都是不行的,都會被認爲錯誤。

實數輸出的問題如果沒有特別說明,舍入都是按四捨五入進行。

樣例輸入
4
樣例輸出
50.2654825
數據規模與約定
1 <= r <= 10000。
提示
本題對精度要求較高,請注意π的值應該取較精確的值。你可以使用常量來表示π,比如PI=3.14159265358979323,也可以使用數學公式來求π,比如PI=atan(1.0)*4。

代碼詳細:

r = int(input())
PI=3.1415926535
area = r**2 * PI
print('%.7f' % area)

試題 入門訓練 序列求和

資源限制
時間限制:1.0s   內存限制:256.0MB
問題描述
求1+2+3+...+n的值。
輸入格式
輸入包括一個整數n。
輸出格式
輸出一行,包括一個整數,表示1+2+3+...+n的值。
樣例輸入
4
樣例輸出
10
樣例輸入
100
說明:有一些試題會給出多組樣例輸入輸出以幫助你更好的做題。

一般在提交之前所有這些樣例都需要測試通過纔行,但這不代表這幾組樣例數據都正確了你的程序就是完全正確的,潛在的錯誤可能仍然導致你的得分較低。

樣例輸出
5050
數據規模與約定
1 <= n <= 1,000,000,000。
說明:請注意這裏的數據規模。

本題直接的想法是直接使用一個循環來累加,然而,當數據規模很大時,這種“暴力”的方法往往會導致超時。此時你需要想想其他方法。你可以試一試,如果使用1000000000作爲你的程序的輸入,你的程序是不是能在規定的上面規定的時限內運行出來。

本題另一個要值得注意的地方是答案的大小不在你的語言默認的整型(int)範圍內,如果使用整型來保存結果,會導致結果錯誤。

如果你使用C++或C語言而且準備使用printf輸出結果,則你的格式字符串應該寫成%I64d以輸出long long類型的整數。
def sum():
    n = int(input())
    return n*(1+n)/2 # 等差數列時間短 直接使用a+b會超時
s = int(sum())
print(s)

試題 入門訓練 A+B問題

資源限制
時間限制:1.0s   內存限制:256.0MB
問題描述
輸入A、B,輸出A+B。
說明:在“問題描述”這部分,會給出試題的意思,以及所要求的目標。
輸入格式
輸入的第一行包括兩個整數,由空格分隔,分別表示A、B。
說明:“輸入格式”是描述在測試你的程序時,所給的輸入一定滿足的格式。

做題時你應該假設所給的輸入是一定滿足輸入格式的要求的,所以你不需要對輸入的格式進行檢查。多餘的格式檢查可能會適得其反,使用你的程序錯誤。

在測試的時候,系統會自動將輸入數據輸入到你的程序中,你不能給任何提示。比如,你在輸入的時候提示“請輸入A、B”之類的話是不需要的,這些多餘的輸出會使得你的程序被判定爲錯誤。

輸出格式
輸出一行,包括一個整數,表示A+B的值。
說明:“輸出格式”是要求你的程序在輸出結果的時候必須滿足的格式。

在輸出時,你的程序必須滿足這個格式的要求,不能少任何內容,也不能多任何內容。如果你的內容和輸出格式要求的不一樣,你的程序會被判斷爲錯誤,包括你輸出了提示信息、中間調試信息、計時或者統計的信息等。

樣例輸入
12 45
說明:“樣例輸入”給出了一組滿足“輸入格式”要求的輸入的例子。

這裏給出的輸入只是可能用來測試你的程序的一個輸入,在測試的時候,還會有更多的輸入用來測試你的程序。

樣例輸出
57
說明:“樣例輸出”給出了一組滿足“輸出格式”要求的輸出的例子。

樣例輸出中的結果是和樣例輸入中的是對應的,因此,你可以使用樣例的輸入輸出簡單的檢查你的程序。

要特別指出的是,能夠通過樣例輸入輸出的程序並不一定是正確的程序,在測試的時候,會用很多組數據進行測試,而不侷限於樣例數據。有可能一個程序通過了樣例數據,但測試的時候仍只能得0分,可能因爲這個程序只在一些類似樣例的特例中正確,而不具有通用性,再測試更多數據時會出現錯誤。

比如,對於本題,如果你寫一個程序不管輸入是什麼都輸入57,則樣例數據是對的,但是測試其他數據,哪怕輸入是1和2,這個程序也輸出57,則對於其他數據這個程序都不正確。

數據規模與約定
-10000 <= A, B <= 10000。
說明:“數據規模與約定”中給出了試題中主要參數的範圍。

這個範圍對於解題非常重要,不同的數據範圍會導致試題需要使用不同的解法來解決。比如本題中給的A、B範圍不大,可以使用整型(int)來保存,如果範圍更大,超過int的範圍,則要考慮其他方法來保存大數。

有一些範圍在方便的時候是在“問題描述”中直接給的,所以在做題時不僅要看這個範圍,還要注意問題描述。

代碼詳細:

a,b=map(int,input().split())
print(a+b)

試題 基礎練習 數列排序

資源限制
時間限制:1.0s   內存限制:512.0MB
問題描述
  給定一個長度爲n的數列,將這個數列按從小到大的順序排列。1<=n<=200
輸入格式
  第一行爲一個整數n。
  第二行包含n個整數,爲待排序的數,每個整數的絕對值小於10000。
輸出格式
  輸出一行,按從小到大的順序輸出排序後的數列。
樣例輸入
5
8 3 6 4 9
樣例輸出
3 4 6 8 9

代碼詳細:

n = int(input())
list = list(map(int, input().split()))
list = sorted(list)
for i in range(len(list)):
    print(list[i], end= ' ')

試題 基礎練習 十六進制轉八進制

  資源限制
時間限制:1.0s   內存限制:512.0MB
問題描述
  給定n個十六進制正整數,輸出它們對應的八進制數。

輸入格式
  輸入的第一行爲一個正整數n (1<=n<=10)。
  接下來n行,每行一個由0~9、大寫字母A~F組成的字符串,表示要轉換的十六進制正整數,每個十六進制數長度不超過100000。

輸出格式
  輸出n行,每行爲輸入對應的八進制正整數。

  【注意】
  輸入的十六進制數不會有前導0,比如012A。
  輸出的八進制數也不能有前導0。

樣例輸入
  2
  39
  123ABC

樣例輸出
  71
  4435274

  【提示】
  先將十六進制數轉換成某進制數,再由某進制數轉換成八進制。

代碼詳細:

n = int(input())

for line in range(n):
    num = input()
    ans = format(int(num, 16), 'o')
    print(ans)

詳細可以查閱python的int函數和format函數轉換進制

試題 基礎練習 十六進制轉十進制

資源限制
時間限制:1.0s   內存限制:512.0MB
問題描述
  從鍵盤輸入一個不超過8位的正的十六進制數字符串,將它轉換爲正的十進制數後輸出。
  注:十六進制數中的10~15分別用大寫的英文字母A、B、C、D、E、F表示。
樣例輸入
FFFF
樣例輸出
65535

代碼詳細:

n = input()
print(int(n, 16))

試題 基礎練習 十進制轉十六進制

資源限制
時間限制:1.0s   內存限制:512.0MB
問題描述
  十六進制數是在程序設計時經常要使用到的一種整數的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16個符號,分別表示十進制數的0至15。十六進制的計數方法是滿16進1,所以十進制數16在十六進制中是10,而十進制的17在十六進制中是11,以此類推,十進制的30在十六進制中是1E。
  給出一個非負整數,將它表示成十六進制的形式。
輸入格式
  輸入包含一個非負整數a,表示要轉換的數。0<=a<=2147483647
輸出格式
  輸出這個整數的16進製表示
樣例輸入
30
樣例輸出
1E

代碼詳細:

n = int(input())
print(format(n, 'X')) #X爲大寫,x是小寫

試題 基礎練習 特殊迴文數

資源限制
時間限制:1.0s   內存限制:512.0MB
問題描述
  123321是一個非常特殊的數,它從左邊讀和從右邊讀是一樣的。
  輸入一個正整數n, 編程求所有這樣的五位和六位十進制數,滿足各位數字之和等於n 。
輸入格式
  輸入一行,包含一個正整數n。
輸出格式
  按從小到大的順序輸出滿足條件的整數,每個整數佔一行。
樣例輸入
52
樣例輸出
899998
989989
998899
數據規模和約定
  1<=n<=54。

代碼詳細:

def is_pal(num):
    num = str(num)
    if num == num[::-1]:
        return True
    else:
        return False
def sum_num(num):
    sum = 0
    num = str(num)
    for i in range(len(num)):
        sum += int(num[i])
    return sum

if __name__ == '__main__':
    n = int(input())
    for num in range(10000, 1000000):
        if is_pal(num) and sum_num(num) == n:
            print(num)

試題 基礎練習 迴文數

資源限制
時間限制:1.0s   內存限制:512.0MB
問題描述
  1221是一個非常特殊的數,它從左邊讀和從右邊讀是一樣的,編程求所有這樣的四位十進制數。
輸出格式
  按從小到大的順序輸出滿足條件的四位十進制數。

代碼詳細:

def is_pal(num):
    num = str(num)
    if num == num[::-1]:
        return True
    else:
        return False
if __name__ == '__main__':
    for i in range(1000, 10000):
        if is_pal(i):
            print(i)

試題 基礎練習 特殊的數字

問題描述
  153是一個非常特殊的數,它等於它的每位數字的立方和,即153=1*1*1+5*5*5+3*3*3。編程求所有滿足這種條件的三位十進制數。
輸出格式
  按從小到大的順序輸出滿足條件的三位十進制數,每個數佔一行。

代碼詳細:

def is_ans(num):
    num_sum = pow(int(str(num)[0]), 3) + pow(int(str(num)[1]), 3) + pow(int(str(num)[2]), 3)
    if num == num_sum:
        return True

for ans in range(100, 1000):
    if is_ans(ans):
        print(ans)

這裏使用了str轉換字符串取位數,或者可以直接用除法取位數

def is_ans(num):
    a = num % 10
    b = (num // 10) % 10
    c = (num // 100) % 10
    if num == pow(a, 3) + pow(b, 3) + pow(c, 3):
        return True

for ans in range(100, 1000):
    if is_ans(ans):
        print(ans)

試題 基礎練習 楊輝三角形

問題描述
楊輝三角形又稱Pascal三角形,它的第i+1行是(a+b)i的展開式的係數。

  
它的一個重要性質是:三角形中的每個數字等於它兩肩上的數字相加。

  
下面給出了楊輝三角形的前4行:

  
   1

  
  1 1

  
 1 2 1

  
1 3 3 1

  
給出n,輸出它的前n行。

輸入格式
輸入包含一個數n。

輸出格式
輸出楊輝三角形的前n行。每一行從這一行的第一個數開始依次輸出,中間使用一個空格分隔。請不要在前面輸出多餘的空格。
樣例輸入
4
樣例輸出
1
1 1
1 2 1
1 3 3 1
數據規模與約定
1 <= n <= 34。
def triangles(num):
    n = [1]
    while num > 0:
        for i in range(len(n)):
            print(n[i], end=' ') # 將列表轉爲要求的格式
        n = [1] + [n[i] + n[i+1] for i in range(len(n) - 1)] + [1]
        num -= 1
        print()                  # 換行
if __name__ == '__main__':
    n = int(input())
    triangles(n)

試題 基礎練習 查找整數

問題描述
給出一個包含n個整數的數列,問整數a在數列中的第一次出現是第幾個。

輸入格式
第一行包含一個整數n。

第二行包含n個非負整數,爲給定的數列,數列中的每個數都不大於10000。

第三行包含一個整數a,爲待查找的數。

輸出格式
如果a在數列中出現了,輸出它第一次出現的位置(位置從1開始編號),否則輸出-1。
樣例輸入
6
1 9 4 8 3 9
9
樣例輸出
2
數據規模與約定
1 <= n <= 1000。
def is_ans(num, list):
    for i in range(len(list)):
        if num == list[i]:
            print(i+1)
            break
    if num not in list:
        print(-1)


if __name__ == '__main__':
    n = int(input())
    list = list(map(int, input().split()))
    num = int(input())
    is_ans(num, list)

試題 基礎練習 數列特徵

問題描述
給出n個數,找出這n個數的最大值,最小值,和。

輸入格式
第一行爲整數n,表示數的個數。

第二行有n個數,爲給定的n個數,每個數的絕對值都小於10000。

輸出格式
輸出三行,每行一個整數。第一行表示這些數中的最大值,第二行表示這些數中的最小值,第三行表示這些數的和。
def is_ans(n, list):
    list = sorted(list)
    max = list[-1]
    min = list[0]
    sum = 0
    for i in list:
        sum += i
    print(max)
    print(min)
    print(sum)

if __name__ == '__main__':
    n = int(input())
    list = list(map(int, input().split()))
    is_ans(n, list)

試題 基礎練習 字母圖形

問題描述
利用字母可以組成一些美麗的圖形,下面給出了一個例子:

ABCDEFG

BABCDEF

CBABCDE

DCBABCD

EDCBABC

這是一個5行7列的圖形,請找出這個圖形的規律,並輸出一個n行m列的圖形。

輸入格式
輸入一行,包含兩個整數n和m,分別表示你要輸出的圖形的行數的列數。
輸出格式
輸出n行,每個m個字符,爲你的圖形。
樣例輸入
5 7
樣例輸出
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
def is_ans(n, m):
    graph = [[0 for j in range(m)] for i in range(n)]
    for i in range(n):
        for j in range(m):
            if j >= i:
                graph[i][j] = chr(ord('A')+ j - i)
            else:
                graph[i][j] = chr(ord('A') + i - j)
    return graph
if __name__ == '__main__':
    n, m = map(int, input().split())
    gragh = is_ans(n ,m)
    for i in range(n):
        for j in range(m):
            print(gragh[i][j], end='')
        print()

參考鏈接

試題 基礎練習 01字串

問題描述
對於長度爲5位的一個01串,每一位都可能是0或1,一共有32種可能。它們的前幾個是:

00000

00001

00010

00011

00100

請按從小到大的順序輸出這32種01串。

輸入格式
本試題沒有輸入。
輸出格式
輸出32行,按從小到大的順序每行一個長度爲5的01串。
樣例輸出
00000
00001
00010
00011
<以下部分省略>
for i in range(32):
    print("{0:0>5}".format(format(i, 'b')))

或者使用zfill函數

for i in range(32):
    print(format(i, 'b').zfill(5))

試題 基礎練習 閏年判斷

問題描述
給定一個年份,判斷這一年是不是閏年。

當以下情況之一滿足時,這一年是閏年:

1. 年份是4的倍數而不是100的倍數;

2. 年份是400的倍數。

其他的年份都不是閏年。

輸入格式
輸入包含一個整數y,表示當前的年份。
輸出格式
輸出一行,如果給定的年份是閏年,則輸出yes,否則輸出no。
def is_leapyear(num):
    if num % 4 == 0 and num % 100 != 0 or num % 400 == 0:
        return True
    return False

if __name__ == '__main__':
    num = int(input())
    if is_leapyear(num):
        print('yes')
    else:
        print('no')

試題 基礎練習 階乘計算

n = int(input())
ans = 1
for i in range(1, n+1):
    ans =  ans * i

print(ans)

試題 基礎練習 高精度加法

這道題挺迷的,python比其他語言的方便用途之一就是大數的處理
藍橋杯滿分通過

# python 大數
a = int(input())
b = int(input())
print(a+b)

正確做法:

將每個大數存入列表中,一一相加,進位的進位,最後輸出ans_num
def change_length(str_num, l):
    # 添加前導0
    str_num = '0' * (l -len(str_num)) + str_num
    return str_num

if __name__ == '__main__':
    num1 = input()
    num2 = input()
    # 修改長度
    if len(num1) > len(num2):
        num2 = change_length(num2, len(num1))
    elif len(num1) < len(num2):
        num1 = change_length(num1, len(num2))
    # 結果最多比最長的num長1個單位
    ans_num = [0 for _ in range(len(num1) + 1)]
    # 進位
    k = 0

    for i in range(len(num1)):
        val = k + int(num1[len(num1) - i - 1]) + int(num2[len(num2) - i - 1])
        ans_num[len(num1) - i] = val % 10
        k = 0
        if  val >= 10:
            k = int(val // 10)

    if k != 0:
        ans_num[0] = k
        for i in range(len(ans_num) - 1):
            print(ans_num[i], end='')
        print(ans_num[-1])
    else:
        for i in range(len(ans_num) - 2):
            print(ans_num[i+1], end='')
        print(ans_num[-1])

試題 基礎練習 Huffuman樹

n = int(input())
value = 0
list = list(map(int, input().split()))

for i in range(n - 1):
    list = sorted(list)
    value += list[0] + list[1]
    value_list = list[0] + list[1]
    list.pop(0)
    list.pop(0)
    list.append(value_list)
print(value)

試題 基礎練習 2n皇后問題

此題先留個坑,目前只解決了N皇后的思路
方法1:dfs深度優先搜索

class Solution(object):
    def solveNQueens(self, n):

        k = 0
        ans, q = [], [None] * n

        def dfs(k, n):
            if k == n:
                tmp = []
                for i in range(n):
                    s = ""
                    for j in range(n):
                        s += "Q" if q[i] == j else '.'
                    tmp.append(s)
                ans.append(tmp)

            else:
                for j in range(n):
                    if self.place(k, j, q):
                        q[k] = j
                        dfs(k + 1, n)

        dfs(k, n)
        return ans, len(ans)

    def place(self, k, j, q):
        for i in range(k):
            if q[i] == j or abs(q[i] - j) == abs(i - k):
                return False
        return True

if __name__ == '__main__':
    solu = Solution()
    # solu.solveNQueens(4)
    print(solu.solveNQueens(4)) # 當爲8時就是8皇后問題

輸出:

[['.Q..', '...Q', 'Q...', '..Q.'], ['..Q.', 'Q...', '...Q', '.Q..']]
4個皇后時的兩種情況

方法2:回溯法

def queen(A, cur=0):

    # 遞歸回溯思想解決n皇后問題
    if cur == len(A): # 所有的皇后都正確放置完畢,輸出每個皇后所在的位置
        tmp = []
        for i in range(n):
            s = ''
            for j in range(n):
                s+='Q' if A[i] == j else '.'
            tmp.append(s)
        ans.append(tmp)
        return 0
    for col in range(len(A)):
        A[cur], flag = col, True
        for row in range(cur): # 檢測本次所放皇后的位置是否在同行同列或同一對角線上
            if A[row] == col or abs(col - A[row]) == cur - row: # 是的話,該位置不能放,向上回溯
                flag = False
                break
        if flag: # 否的話,繼續放下一個皇后
            queen(A, cur+1)


n = int(input())
ans = []
queen([None] * n)
print(ans)

上述算法簡述了N皇后的放置方法,這裏同理。

思路:

先在條件合法的情況下放置白皇后,並且將白皇后暫時存儲在tmpWhite數組中。
然後在白皇后全部放置的基礎上,開始放置黑皇后
def correctWhite(tmpWhite, row):
    if arr[row][tmpWhite[row]] == 1: # tmpWhite[row]表示第幾列 ,如果此位置是1, 則表示可以放置
        for i in range(row):        # 判斷條件爲不在同一列,和不在同一對角線上
            if abs(tmpWhite[i] - tmpWhite[row]) == abs(i - row) or tmpWhite[i] == tmpWhite[row]:
                return False
        return True

def correctBlack(tmpBlack, row, tmpWhite):
    if arr[row][tmpBlack[row]] == 1 and tmpBlack[row] != tmpWhite[row]: # tmpBlack[row]表示第幾列 ,如果此位置是1和此位置不和白皇后衝突, 則表示可以放置
        for i in range(row):            # 判斷條件爲不在同一列,和不在同一對角線上
            if abs(tmpBlack[i] - tmpBlack[row]) == abs(i - row) or tmpBlack[i] == tmpBlack[row]:
                return False
        return True

def dfs_Black(tmpBlack, row):
    if row == n: # 此時黑皇后和白皇后的位置全部確定, 將結果輸入到ans列表中
        ans.append(tmpBlack[:])
        return    # 退出遞歸
    else:
        for col in range(n):
            tmpBlack[row] = col
            if correctBlack(tmpBlack, row, tmpWhite): # 如果位置合法
                dfs_Black(tmpBlack, row + 1)         # 開始下一個黑皇后的放置


def dfs_White(tmpWhite, row):
    if row == n:   # 如果此時確定了白皇后的全部位置,開始放置黑皇后
        dfs_Black(tmpBlack,0)
    else:
        for col in range(n):    # 從第一個白皇后開始放置
            tmpWhite[row] = col
            if correctWhite(tmpWhite, row): # 如果位置可以放置
                dfs_White(tmpWhite, row+1)  # 開始放置下一個白皇后
if __name__ == '__main__':

    # 輸入n與棋盤, 其中棋盤用二維數組表示
    n = int(input())
    arr = [list(map(int, input().split())) for _ in range(n)]
    # 設置臨時存放黑白皇后的棋盤
    tmpWhite = [None for _ in range(n)]
    tmpBlack = [None for _ in range(n)]
    ans = []
    # 先從白皇后放置開始
    dfs_White(tmpWhite, 0)
    print(len(ans))

試題 基礎練習 報時助手

h, m = map(int, input().split())

time = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine',
        10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen',
        17: 'seventeen', 18: 'eighteen', 19: 'nineteen', 20: 'twenty', 21: 'twenty one', 22: 'twenty two',
        23: 'twenty three', 30: 'thirty', 40: 'forty', 50: 'fifty'}

if m == 0:
    print(time[h] + ' o\'clock')
else:
    print(time[h], end=' ')
    if 0 < m <= 20 or m == 30 or m == 40 or m == 50:
        print(time[m])
    elif 20 < m < 30:
        print(time[20] + ' ' + time[m - 20])
    elif 30 < m < 40:
        print(time[30] + ' ' + time[m - 30])
    elif 40 < m < 50:
        print(time[40] + ' ' + time[m - 40])
    else:
        print(time[50] + ' ' + time[m - 50])

試題 基礎練習 回形取數

思路:

通過x表示縱座標,因爲x表示行數,行數+1時縱座標就會加一
同理 y表示橫座標
n, m = map(int, input().split())
tmp = [] # 存放答案
vis = [[0 for i in range(m)] for i in range(n)] # 驗證位置是否走過 當vis[x][y] = 1時即爲走過
arr = [list(map(int, input().split())) for _ in range(n)]
# 注意: 向下爲x, 向右爲y
x = 0 # 當前縱座標
y = 0 # 當前橫座標
while len(tmp) < n*m :
    while x < n and vis[x][y] == 0:
        tmp.append(arr[x][y])
        vis[x][y] = 1
        x += 1  # 縱座標加一
    x -= 1 # 將上步多餘的步數刪除,防止溢出
    y += 1 # 將橫座標右移
    while y < m and vis[x][y] == 0:
        tmp.append(arr[x][y])
        vis[x][y] = 1
        y += 1
    x -= 1 # 將縱座標減一
    y -= 1 # 將上步多餘步數刪除,防止溢出
    while x >= 0 and vis[x][y] == 0:
        tmp.append(arr[x][y])
        vis[x][y] = 1
        x -= 1 # 將縱座標上移
    x += 1 # 將上步多餘步數刪除,防止溢出
    y -= 1 # 將橫座標左移
    while y >=0 and vis[x][y] == 0:
        tmp.append(arr[x][y])
        vis[x][y] = 1
        y -= 1 # 將橫座標左移
    y += 1 # 將上步多餘步數刪除
    x += 1 # 將縱座標下移

# 輸出數據
for i in range(len(tmp)):
    print(tmp[i], end=' ')

試題 基礎練習 龜兔賽跑預測

data = list(map(int, input().split()))
rabbit = turtle = 0
time = 0 #目前的時間
flag = False
while True:
    if  rabbit == data[-1] or turtle == data[-1]: # 到達終點
        break
    if  rabbit - turtle >= data[2]:
        for i in range(data[3]):
            turtle += data[1]
            time += 1
            if turtle >= data[-1]:
                flag = True
                break
        if flag:
            break

    time += 1
    rabbit += data[0]
    turtle += data[1]

if rabbit > turtle:  # 誰先到達終點,誰的距離大
    print('R')
    print(time)
elif rabbit < turtle:
    print('T')
    print(time)
else:  # 相等則平局
    print('D')
    print(time)

試題 基礎練習 芯片測試

思路:

這道題需仔細審題, 當好芯片測好芯片時爲1, 測壞芯片時爲0,壞芯片測試的時候情況不一定。
所以我們可以知道 當每一列0的個數大於n的一半時,此芯片爲壞芯片
按列查找
n = int(input())
arr = [list(map(int, input().split())) for _ in range(n)]
tmp = [True] * n # tmp[i]爲False時爲壞芯片
for i in range(n):
    count = 0
    for j in range(n):
        if arr[j][i] == 0: # 按列查找
            count += 1
        if count >= n/2:
            tmp[i] = False
            break
for i in range(n):
    if tmp[i]:
        print(i+1, end=' ')

試題 基礎練習 FJ的字符串

n = int(input())
str = 'ABA'
if n == 1:
    print('A')
elif n == 2:
    print('ABA')
else:
    for i in range(3, n+1):
        str = str + chr((i + 64)) + str
    print(str)

試題 基礎練習 Sine之舞

思路:

遞歸調用
def Sine_An(n, k):
    if n == k: # 返回值
        return
    print('sin(%d' % (n+1), end='')

    if n + 1 != k: # 當n小於輸入的值,即後面還有式子
        if n % 2 == 1: # 如果n是奇數 輸出+號
            print('+', end='')
        else:         # 如果n是偶數 輸出-號
            print('-', end='')
    else:          # 如果後面沒有式子輸出右括號
        print(')', end='')

    Sine_An(n+1, k)

def Sine_Sn(n):
    k = t = 1

    if n == 0:
        return

    for i in range(n-1): # 補全左邊括號
        print('(', end='')

    while n != 0:
        Sine_An(0,k)
        for i in range(t-1):
            print(')', end='') # 補全An的右括號
        print('+%d' % n, end='')
        if n !=1:
            print(')', end='')

        k+=1
        t+=1
        n-=1
if __name__ == '__main__':
    n = int(input())
    Sine_Sn(n)

試題 基礎練習 數的讀法

思路:

考慮多種情況
如前置1有的位置是不讀的,11讀作shi yi而不是yi shi yi
連續0的處理問題
n = input()

pin_yin = {'0': 'ling', '1': 'yi', '2': 'er', '3': 'san', '4': 'si', '5': 'wu',
           '6': 'liu', '7': 'qi', '8': 'ba', '9': 'jiu'}
pin_yin_2 = {0: '', 1: '', 2: 'shi', 3: 'bai', 4: 'qian', 5: 'wan', 6: 'shi',
             7: 'bai', 8: 'qian', 9: 'yi', 10: 'shi'}
n = n + ' '
#
l = len(n) - 1
for i in range(l):
    j = int(n[i])
    if j != 0:  # 不爲0時的讀法
        if (l - i == 2 or l - i == 6 or l - i == 10) and j == 1:
            # 在十位,十萬位,十億位置且位於開頭的1不讀
            # 例子:
            # 1111111111 會讀出 yi shi yi yi yi qian yi bai yi shi yi wan yi qian yi bai yi shi yi
            # 111111 會讀出 yi shi yi wan yi qian yi bai yi shi yi
            # 11 會讀出 yi shi yi
            # 加上此約束後,則不會讀出開頭的 yi
            if i != 0:  # 第一個1不輸出1, 若不添加此條件,12會讀出 yi shi er
                print(pin_yin['1'], end=' ')
            print(pin_yin_2[2], end=' ')
            continue
        print(pin_yin[n[i]], end=' ')
        print(pin_yin_2[l - i], end=' ')
    else:  # 處理0的讀法問題
        if l - i == 5 or l - i == 9:  # 如果此0是在萬位或億位,則讀出萬或億
            print(pin_yin_2[l - i], end=' ')
        if n[i + 1] == '0' or i == l - 1:  # 如果後一位仍然爲0,或者,當前是最後一位,則不讀此0
            continue
        print(pin_yin['0'], end=' ')  # 否則纔讀出這個零

試題 基礎練習 完美的代價

思路:

兩種情況:
1.impossible的情況:如果有一個字符出現的次數是奇數次數,而且n是偶數,那麼不可能構成迴文。
如果n是奇數,但是已經有一個字符出現的次數是奇數次數了,那麼如果又有一個字符是奇數次數,就不可能構成迴文。
2.如果n是奇數,計算中間那個字符交換的次數的時候,不需要模擬把這個數移動到中間去,因爲移動到中間的話假設有一對數都在左邊或者都在右邊。那麼交換成迴文的時候就要經過中間,就會每次把cnt多加了1,而這個1是沒有必要的,因爲可以所有的迴文移動完了之後再把這個獨立的奇數移動過去,才能保證交換次數最少

原文鏈接:https://blog.csdn.net/qq_31910669/article/details/103641497

該方法藍橋杯有一組數據超時

n = int(input())

pal = list(input())

count = flag = 0  # count計數,flag判斷是否已經有一個單獨的奇個數的字符了

m = n - 1

for i in range(m):  # 從頭遍歷到倒數第二個字符
    for k in range(m, i - 1, -1):  # 從後面往前一直到i尋找和pal[i]相同的pal[k]
        if k == i:  # 如果找不到相同的
            if n % 2 == 0 or flag == 1:  # impossible的兩種情況
                print('Impossible')
                exit()
            flag = 1
            count += int(n / 2) - i
        elif pal[k] == pal[i]:
            for j in range(k, m):  # 找到相同的,進行交換
                pal[j], pal[j + 1] = pal[j + 1], pal[j]
                count += 1  # 計數器加1
            m -= 1  # 最後拍好序的不在進行比較
            break

print(count)

方法2:
思路來源:幹啥啥不會~

def is_pal(n, s):
    temp = set()
    if n % 2 == 0:
        for i in range(26):
            if s.count(chr(ord('a') + i)) % 2 != 0:
                print('Impossible') # 如果字符串字符爲偶數,但是存在不成對字符
                return False
        else:
            return True
    else:
        for i in range(26):
            if s.count(chr(ord('a') + i)) % 2 != 0:
                temp.add(chr(ord('a') + i))
            if len(temp) > 1:
                print('Impossible')  # 如果字符串字符爲奇數,但是存在不成對字符超過一個
                return False
        else:
            return True

def count_step(n, s, s1):
    global ans
    for i in range(n // 2):
        if s[i:].count(s[i]) != 1:
            temp = s1[:n - i].index(s[i])
            s1.pop(temp)
            ans += temp
            s = s1[::-1]
        else:
            ans += n // 2 - i
            s[i] = None # 將此奇數移動到中間後清除
            s1 = s[::-1]
    return ans

if __name__ == '__main__':
    n = int(input()) # 字符串的長度
    s = list(input()) # 輸入字符串
    s1 = s[::-1]
    ans = 0

    if is_pal(n, s):    # 如果是迴文數 計算挪動的步數
        print(count_step(n, s, s1))

試題 基礎練習 矩形面積交

問題描述
  平面上有兩個矩形,它們的邊平行於直角座標系的X軸或Y軸。對於每個矩形,我們給出它的一對相對頂點的座標,請你編程算出兩個矩形的交的面積。
輸入格式
  輸入僅包含兩行,每行描述一個矩形。
  在每行中,給出矩形的一對相對頂點的座標,每個點的座標都用兩個絕對值不超過10^7的實數表示。
輸出格式
  輸出僅包含一個實數,爲交的面積,保留到小數後兩位。

思路:

重點是找到兩個矩形產生交集的條件
矩陣1的對角點座標的橫座標取最小, 矩陣2的對角點座標的橫座標取最小,然後再從這兩個值中取最大,得x1
矩陣1的對角點座標的橫座標取最大, 矩陣2的對角點座標的橫座標取最大,然後再從這兩個值中取最小,得x2
如果x1<x2,這兩個矩形纔會有交集
縱座標同理
最後交集的面積就爲:
area = (x2 - x1) * (y2 - y1)
原文鏈接:https://blog.csdn.net/qq_31910669/article/details/103641497
題號2.26

list1 = list(map(float, input().split()))
list2 = list(map(float, input().split()))

x1 = max(min(list1[0], list1[2]), min(list2[0], list2[2]))
x2 = min(max(list1[0], list1[2]), max(list2[0], list2[2]))
y1 = max(min(list1[1], list1[3]), min(list2[1], list2[3]))
y2 = min(max(list1[1], list1[3]), max(list2[1], list2[3]))

if x1 < x2 and y1 < y2:
    area = (x2 - x1)*(y2 - y1)
    print('%.2f' % area)
else:
    print('%.2f' % 0.00)

試題 基礎練習 矩陣乘法

問題描述
  給定一個N階矩陣A,輸出A的M次冪(M是非負整數)
  例如:
  A =
  1 2
  3 4
  A的2次冪
  7 10
  15 22
輸入格式
  第一行是一個正整數N、M(1<=N<=30, 0<=M<=5),表示矩陣A的階數和要求的冪數
  接下來N行,每行N個絕對值不超過10的非負整數,描述矩陣A的值
輸出格式
  輸出共N行,每行N個整數,表示A的M次冪所對應的矩陣。相鄰的數之間用一個空格隔開
def slove(N, rect1, rect_ans):
    rect2 = [[0 for _ in range(N)] for _ in range(N)]
    for i in range(N):  # 行
        for j in range(N):  # 列
            for n in range(N):
                rect2[i][j] += rect1[i][n] * rect_ans[n][j]
    return rect2

if __name__ == '__main__':
    N, M =map(int, input().split())     # 輸入數據
    rect1 = [[] for _ in range(N)]       # 定義矩陣

    for i in range(N):
        arr = input().split()
        for j in range(N):
            rect1[i].append(int(arr[j])) # 輸入數據

    if M > 0:
        # 矩陣的冪
        rect_ans = rect1
        for i in range(M-1):
            rect_ans = slove(N, rect1, rect_ans)
    else:
        # 冪等於0時,輸出單位矩陣
        rect_ans = [[0 for _ in range(N)] for _ in range(N)]
        for i in range(N):
            rect_ans[i][i] = 1

    # 格式化輸出
    for i in range(N):
        for j in range(N):
            print(rect_ans[i][j], end=' ')
        print()

試題 基礎練習 分解質因數

問題描述
  求出區間[a,b]中所有整數的質因數分解。
輸入格式
  輸入兩個整數a,b。
輸出格式
  每行輸出一個數的分解,形如k=a1*a2*a3...(a1<=a2<=a3...,k也是從小到大的)(具體可看樣例)

目前此題代碼優化的不是很好, 有兩組數據超時,有更好的可以發在評論區分享,互相學習
在這裏插入圖片描述

def slove(num):
    list = []
    tmp = 2
    if num == tmp:
        print(num,'=', num, sep='')
    else:
        print(num,'=', sep='', end='')
        while num >= tmp:
            if num % tmp ==0:
                list.append(tmp)
                num = num / tmp
            else:
                tmp += 1
        for i in range(len(list)-1):
            print(list[i], '*', sep='', end='')
        print(list[-1])
if __name__ == '__main__':
    a, b = map(int, input().split())
    for i in range(a, b+1):
        slove(i)

下方代碼完美通過,思路來源幹啥啥不會~
在這裏插入圖片描述

def solve(res, n, result):
    for i in range(2, n+1):
        if n % i ==0:
            res += str(i)
            n = n // i
            if n == 1:
                return res
            elif n in result.keys():
                res += '*'
                res += result[n]
                return res
            else:
                res += '*'
                return solve(res, n, result)
        else:
            continue

if __name__ == '__main__':
    a, b = map(int, input().split()) # 輸入兩個整數
    result = {}   # result存放值與其分解質因數的對應關係
    # {3: '3', 4: '2*2', 5: '5', 6: '2*3', 7: '7', 8: '2*2*2', 9: '3*3', 10: '2*5'}
    
    for i in range(a, b+1):
        res = ''  # 存放各個因數
        result[i] = solve(res, i, result)
    
    # 輸出
    for k, v in result.items():
        s = str(k)+ '='+ str(v)
        print(s)

試題 基礎練習 字符串對比

問題描述
  給定兩個僅由大寫字母或小寫字母組成的字符串(長度介於1到10之間),它們之間的關係是以下4中情況之一:
  1:兩個字符串長度不等。比如 Beijing 和 Hebei
  2:兩個字符串不僅長度相等,而且相應位置上的字符完全一致(區分大小寫),比如 Beijing 和 Beijing
  3:兩個字符串長度相等,相應位置上的字符僅在不區分大小寫的前提下才能達到完全一致(也就是說,它並不滿足情況2)。比如 beijing 和 BEIjing
  4:兩個字符串長度相等,但是即使是不區分大小寫也不能使這兩個字符串一致。比如 Beijing 和 Nanjing
  編程判斷輸入的兩個字符串之間的關係屬於這四類中的哪一類,給出所屬的類的編號。
輸入格式
  包括兩行,每行都是一個字符串
輸出格式
  僅有一個數字,表明這兩個字符串的關係編號
def slove(str1, str2):
    if len(str1) != len(str2):
        return 1
    else:
        if str1 == str2:
            return 2
        elif str1.lower() != str2.lower():
            return 4
        return 3
if __name__ == '__main__':
    str1 = input()
    str2 = input()
    print(slove(str1, str2))

Python 字符串大小寫轉換

試題 基礎練習 時間轉換

問題描述
  給定一個以秒爲單位的時間t,要求用“<H>:<M>:<S>”的格式來表示這個時間。<H>表示時間,<M>表示分鐘,而<S>表示秒,它們都是整數且沒有前導的“0”。例如,若t=0,則應輸出是“0:0:0”;若t=3661,則輸出“1:1:1”。
輸入格式
  輸入只有一行,是一個整數t(0<=t<=86399)。
輸出格式
  輸出只有一行,是以“<H>:<M>:<S>”的格式所表示的時間,不包括引號。
time = int(input())
hour = time // 3600
minute = (time - hour*3600) // 60
second = (time - hour*3600 - minute*60) % 60

print(hour,':',minute,':',second, sep='')

算法訓練

試題 算法訓練 預測身高

data = list(map(float, input().split()))

if data[0] == 0:
    ans = (data[1]*0.923 + data[2]) / 2
    print("%.3f" % ans)
else:
    ans = (data[1] + data[2]) / 2 * 1.08
    print("%.3f" % ans)

試題 算法訓練 1的個數

'''
問題描述
  輸入正整數n,判斷從1到n之中,數字1一共要出現幾次。例如1123這個數,則出現了兩次1。例如15,那麼從1到15之中,一共出現了8個1。
輸入格式
  一個正整數n
輸出格式
  一個整數,表示1出現的資料
樣例輸入
15
樣例輸出
8
'''
n = int(input())
ans = 0
for i in range(1, n+1):
    strn = str(i)
    ans += strn.count('1')
print(ans)

試題 算法訓練 5-1最小公倍數

'''
問題描述
  編寫一函數lcm,求兩個正整數的最小公倍數。
樣例輸入
一個滿足題目要求的輸入範例。
例:

3 5
樣例輸出
15
'''
# 最小公倍數 lcm = a*b/gcd(a,b)
# gcd爲最大公約數
def gcd(a,b):
    c = a % b
    while c!=0:
        a = b
        b = c
        c = a % b
    return b

if __name__ == '__main__':
    a,b = map(int, input().split())
    lcm = a*b/gcd(a,b)
    print(int(lcm))

試題 算法訓練 6-1 遞歸求二項式係數值

'''
# 方法一 遞歸
def C(k,n):
    if k == n or k == 0:
        return 1
    else:
        return C(k, n-1)+C(k-1,n-1)

k,n = map(int, input().split())
print(C(k,n))
'''

# 方法二 動態規劃
'''
k = 3 n = 10
[0, 0, 0, 0],
[1, 1, 0, 0], 
[1, 2, 1, 0], 
[1, 3, 3, 1], 
[1, 4, 6, 4], 
[1, 5, 10, 10], 
[1, 6, 15, 20], 
[1, 7, 21, 35], 
[1, 8, 28, 56], 
[1, 9, 36, 84], 
[1, 10, 45, 120]
'''
k,n = map(int, input().split())
dp = [[0 for _ in range(k+1)] for _ in range(n+1)]
# k=0時候, 1填入dp數組中
for i in range(1, n+1):
    dp[i][0] = 1

# k=n時候, 1填入dp數組中
for i in range(1, k+1):
    dp[i][i] = 1

for i in range(2, n+1):
    for j in range(1, k+1):
        if i > j:
            dp[i][j] = dp[i-1][j] + dp[i-1][j-1]

print(dp[n][k])

試題 算法訓練 k好數

k, l = map(int, input().split())
mod = 1000000007
ans = 0
dp = [[0 for _ in range(l+1)] for _ in range(k)]

for i in range(k):
    dp[i][1] = 1

for i in range(2, l+1): # 按列遍歷 l表示l位數
    for j in range(k):  # 按行遍歷
        for w in range(k):
            if w != j+1 and w != j-1: # 相鄰的數字不添加
                dp[j][i] = (dp[j][i] + dp[w][i-1])%mod

# 將第l列的數字相加即爲ans
for i in range(1,k):
    ans = (ans + dp[i][l])%mod

print(ans)

試題 算法訓練 區間k大數查詢

'''
問題描述
給定一個序列,每次詢問序列中第l個數到第r個數中第K大的數是哪個。

輸入格式
第一行包含一個數n,表示序列長度。

第二行包含n個正整數,表示給定的序列。

第三個包含一個正整數m,表示詢問個數。

接下來m行,每行三個數l,r,K,表示詢問序列從左往右第l個數到第r個數中,從大往小第K大的數是哪個。序列元素從1開始標號。

輸出格式
總共輸出m行,每行一個數,表示詢問的答案。
樣例輸入
5
1 2 3 4 5
2
1 5 2
2 3 2
樣例輸出
4
2
'''
# 輸入數據
n = int(input())
list_q = list(map(int, input().split()))
m = int(input())

for _ in range(m):
    l,r,k = map(int, input().split())
    ans = list_q[l-1:r]
    ans = sorted(ans, reverse=True)
    print(ans[k-1])

試題 算法訓練 尋找數組中最大值

'''
問題描述
  對於給定整數數組a[],尋找其中最大值,並返回下標。
輸入格式
  整數數組a[],數組元素個數小於1等於100。輸出數據分作兩行:第一行只有一個數,表示數組元素個數;第二行爲數組的各個元素。
輸出格式
  輸出最大值,及其下標
'''
n = int(input())
list1 = list(map(int, input().split()))
max = max(list1)
num = list1.index(max)
print(max,num)

試題 算法訓練 最大的算式

'''
問題描述
  題目很簡單,給出N個數字,不改變它們的相對位置,在中間加入K個乘號和N-K-1個加號,(括號隨便加)使最終結果儘量大。因爲乘號和加號一共就是N-1個了,所以恰好每兩個相鄰數字之間都有一個符號。例如:
  N=5,K=2,5個數字分別爲1、2、3、4、5,可以加成:
  1*2*(3+4+5)=24
  1*(2+3)*(4+5)=45
  (1*2+3)*(4+5)=45
  ……
輸入格式
  輸入文件共有二行,第一行爲兩個有空格隔開的整數,表示N和K,其中(2<=N<=15, 0<=K<=N-1)。第二行爲 N個用空格隔開的數字(每個數字在0到9之間)。
輸出格式
  輸出文件僅一行包含一個整數,表示要求的最大的結果
樣例輸入
5 2
1 2 3 4 5
樣例輸出
120
'''
# 輸入數據
n,k = map(int, input().split())
listq = list(map(int, input().split()))
tmp = listq[0]
# 建立dp數組
dp = [[0 for _ in range(k+1)] for _ in range(n+1)]
dp[1][0] = tmp #  提前將第一個數放入dp數組中,方便下面for循環放置
# 將dp數組第一列數據添加
for i in range(1, n):
    tmp += listq[i]
    dp[i+1][0] = tmp
# 當沒有乘號時
if k == 0:
    print(dp[n][k])
else:
    for j in range(1, k+1): # 按列循環
        for i in range(2, n+1): # 按行循環
            if i > j: # 乘號小於要計算的各個數字
                '''
                ①dp[5][1] = dp[1][0]x(dp[5][0] - dp[1][0]) = 14
                ②dp[5][1] = dp[2][0]x(dp[5][0] - dp[2][0]) = 36
                ③dp[5][1] = dp[3][0]x(dp[5][0] - dp[3][0]) = 54
                ④dp[5][1] = dp[4][0]x(dp[5][0] - dp[4][0]) = 50
                max函數取其中最大的得數
                '''
                for p in range(1,i):
                    dp[i][j] = max(dp[i][j], dp[p][j-1]*(dp[i][0] - dp[p][0]))

    print(dp[n][k])

試題 算法訓練 石子游戲

思路:
首先將數據存入列表中, 然後進行排序, 直接取尾部最大的兩個數

'''
問題描述
  石子游戲的規則如下:
  地上有n堆石子,每次操作可選取兩堆石子(石子個數分別爲x和y)並將它們合併,操作的得分記爲(x+1)×(y+1),對地上的石子堆進行操作直到只剩下一堆石子時停止遊戲。
  請問在整個遊戲過程中操作的總得分的最大值是多少?
輸入格式
  輸入數據的第一行爲整數n,表示地上的石子堆數;第二行至第n+1行是每堆石子的個數。
輸出格式
  程序輸出一行,爲遊戲總得分的最大值。
樣例輸入
10
5105
19400
27309
19892
27814
25129
19272
12517
25419
4053
樣例輸出
15212676150
'''
def solve(arr):
    ans = 0
    arr = sorted(arr)
    for i in range(len(arr) - 1):
        tmp = (arr[-1] + 1) * (arr[-2] + 1)
        num = arr[-1] + arr[-2]
        arr.pop()  # 將最後相加的石子堆彈出
        arr.pop()  # 將最後相加的石子堆彈出
        arr.append(num)
        ans += tmp
    return ans


if __name__ == '__main__':
    n = int(input())
    arr = [int(input()) for _ in range(n)]
    ans = solve(arr)
    print(ans)

試題 算法訓練 Torry的困惑(基本型)

思路:
這裏直接暴力應該可以過, 我這裏使用了一個質數的特性, 一個質數肯定不會被小於它的質數除盡
根據這個特性可以優化代碼

詳細的最優質數代碼

prime = []
        if n == 0 or n == 1 or n == 2:
            print(0)
        for i in range(n + 1):
            prime.append(True)
        for i in range(2, n + 1):
            if prime[i] == True:
                p = i
                j = 2
                while p * j <= n:
                    prime[p * j] = False
                    j += 1
        prime = prime[2:len(prime) - 1]
        ans = prime.count(True)
        return ans

本題代碼:

def is_prime(num):
    for i in tmp: # 遍歷質數數組
        if num % i == 0:
            return False
    tmp.append(num)
    return True


if __name__ == '__main__':
    i = 3 # 如果n大於2, 從數字3開始遍歷
    ans = 2 # 默認填入第一個質數
    tmp = [2] # 質數數組
    n = int(input())
    while True:
        if len(tmp) >= n:
            break
        if is_prime(i):
            ans *= i
        i += 1
    print(ans % 50000)

試題 算法訓練 最小乘積(基本型)

思路:
將兩組數據一個降序排序, 一個升序排序, 遍歷相乘再相加即可

t = int(input())
for _ in range(t):
    ans = 0
    n = int(input())
    arr1 = list(map(int, input().split()))
    arr2 = list(map(int, input().split()))

    numList1 = sorted(arr1)  # 升序
    numList2 = sorted(arr2, reverse=True)  # 降序
    for i in range(n):
        ans += numList1[i] * numList2[i]
    print(ans)

算法提高

試題 算法提高 最長滑雪道

思路:

深度優先搜索(dfs),將搜索到的每個位置的答案存入dp中
def dfs(x, y):
    max_height = 1
    if dp[x][y] > 0: # 如果前面dfs已經將該點的高度存入dp中,則直接返回,不用計算
        return dp[x][y]
    for k in range(4):
        tx = x + next_[k][0]
        ty = y + next_[k][1]
        if tx < 0 or tx >= row or ty < 0 or ty >= col:
            continue
        if arr[tx][ty] >= arr[x][y]:
            continue
        max_height = max(max_height, dfs(tx, ty) + 1)

    dp[x][y] = max_height
    return dp[x][y]

if __name__ == '__main__':
    ans = 0
    row, col = map(int, input().split())
    dp = [[0 for _ in range(col)] for _ in range(row)]
    arr = [list(map(int, input().split())) for _ in range(row)]

    next_ = [[0, 1], [1,0], [0,-1], [-1, 0]]

    for i in range(row):
        for j in range(col):
            ans = max(ans, dfs(i, j))

    print(ans)

試題 算法提高 最長公共子序列

這道題是典型的LCS(Longest Common Subsequence)

具體思路是動態規劃: 詳細可以參考b站視頻: 雖然是英文的但是也很好理解

'''
問題描述
  給定兩個字符串,尋找這兩個字串之間的最長公共子序列。
輸入格式
  輸入兩行,分別包含一個字符串,僅含有小寫字母。
輸出格式
  最長公共子序列的長度。
樣例輸入
abcdgh
aedfhb
樣例輸出
3
樣例說明
  最長公共子序列爲a,d,h。
數據規模和約定
  字串長度1~1000。
'''


def lcs(str1, str2):
    l1 = len(str1)
    l2 = len(str2)
    arr = [[0 for _ in range(l1 + 1)] for _ in range(l2 + 1)]

    for i in range(l2 + 1):
        for j in range(l1 + 1):
            if i == 0 or j == 0:  # arr[0][j] 與 arr[i][0]全部置爲0
                arr[i][j] = 0
            elif i > 0 and j > 0 and str2[i - 1] == str1[j - 1]: # 如果有相等的字符, 則加1
                arr[i][j] = 1 + arr[i - 1][j - 1]
            else:
                arr[i][j] = max(arr[i][j - 1], arr[i - 1][j])

    return arr


if __name__ == '__main__':
    str1 = input()
    str2 = input()
    ansList = lcs(str1, str2)
    print(ansList[-1][-1])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章