以下是本週有所收穫的題目

第一題:

第4章-4 驗證“哥德巴赫猜想” (20 分)

數學領域著名的“哥德巴赫猜想”的大致意思是:任何一個大於2的偶數總能表示為兩個素數之和。比如:24=5+19,其中5和19都是素數。本實驗的任務是設計一個程式,驗證20億以內的偶數都可以分解成兩個素數之和。

輸入格式: 輸入在一行中給出一個(2, 2 000 000 000]範圍內的偶數N。

輸出格式: 在一行中按照格式“N = p + q”輸出N的素數分解,其中p ≤

q均為素數。又因為這樣的分解不唯一(例如24還可以分解為7+17),要求必須輸出所有解中p最小的解。

我的程式碼:

n = int(input())
for i in range(2, n):
flag = 0
for x in range(2, i // 2):
if i % x == 0:
flag = 1
break
if flag == 0:
for x in range(i, n):
if i + x == n:
flag = 0
for y in range(2, x // 2):
if x % y == 0:
flag = 1
break
if flag == 0:
print("%d = %d + %d" % (n, i, x))
exit()

由於演算法不夠好,有兩個測試點顯示執行超時。

別人的程式碼:

#本題難點在於避免數字較大時超時
import math
n = int(input())
for p in range(2,n):
for i in range(2,int(math.sqrt(p))+1):
if p%i == 0:
break
else:
q = n-p
for k in range(2,int(math.sqrt(q))+1):
if q%k == 0:
break
else:
print("{} = {} + {}".format(n,p,q))
break

思考:

1.我想對迴圈的中的變數開根號,但卻一直無法實現,直到我看到別人的程式碼之後才發現原來開完根號之後要轉換為int型別!

int(math.sqrt(p))

2 在找到第一個素數之後另一個素數可以直接用n-x得到,然後再判斷是不是素數。而我的程式碼中卻還要再用一個迴圈找,效率太低。

3 對於判斷素數,還有一個地方值得我學習

for k in range(2,int(math.sqrt(q))+1):
if q%k == 0:
break
else:
print("{} = {} + {}".format(n,p,q))

這裡的if else的用法非常好,注意else的位置,在for的下面。如果沒有一個if符合,則執行else。以後我也應該這樣做。

第二題:

第4章-6 輸出前 n 個Fibonacci數 (15 分) 本題要求編寫程式,輸出菲波那契(Fibonacci)數列的前N項,每行輸出5個,題目保證輸出結果在長整型範圍內。Fibonacci數列就是滿足任一項數字是前兩項的和(最開始兩項均定義為1)的數列,例如:1,1,2,3,5,8,13,...。

輸入格式: 輸入在一行中給出一個整數N(1≤N≤46)。

輸出格式: 輸出前N個Fibonacci數,每個數佔11位,每行輸出5個。如果最後一行輸出的個數不到5個,也需要換行。

如果N小於1,則輸出"Invalid."

輸入樣例1: 7

輸出樣例1:

1 1 2 3 5

8 13

輸入樣例2: 0

輸出樣例2: Invalid.

我的程式碼:

N = int(input())
ls = [1 for x in range(N)]
count = 0
if N < 1:
print("Invalid.")
exit()
for i in range(0, N):
if i == 0 or i == 1:
print("{:=11}".format(ls[i]), end="")
count += 1
continue
ls[i] = (ls[i - 2] + ls[i - 1])
print("{:=11}".format(ls[i]), end="")
count += 1
if count == 5 or i == N - 1:
print()
count = 0

我學到了:

1.格式化輸出: 題目要求輸出的每個數佔11位,在C中可以通過setw函式實現,而在python中可以通過可以直接在print中實現:

print("{:=11}".format(ls[i]), end="")

以下是format的相關知識:

格式限定符:

語法是{}中所帶:號即為格式限定符,如:

填充與對齊 填充常跟對齊一起使用 ^、<、>分別是居中、左對齊、右對齊,後面頻寬度

:號後面帶填充的字元,只能是一個字元,不指定的話預設是用空格填充 例如:’{:<8.3}’.format(0.12345) 輸出為

0.123 ,共佔八個字元位置,可以用來進行輸出對齊;

In [15]: '{:>8}'.format('189') Out[15]: ' 189' In [16]:

'{:0>8}'.format('189') Out[16]: '00000189' In [17]:

'{:a>8}'.format('189') Out[17]: 'aaaaa189' ————————————————

版權宣告:本文為CSDN博主「christianashannon」的原創文章,遵循CC 4.0

BY-SA版權協議,轉載請附上原文出處連結及本宣告。

原文連結:https://blog.csdn.net/christianashannon/article/details/78964961

2.初始化列表:

我在一開始寫的時候,因為列表的長度過短,比較麻煩,後來初始化長度之後就可以了,

之前一直不知道怎麼初始化列表。

ls = [1 for x in range(N)] ## 1處填初始化的值

第三題:

第4章-12 求滿足條件的斐波那契數 (30 分)

斐波那契數,亦稱之為斐波那契數列,指的是這樣一個數列:1、1、2、3、5、8、13、21、……,這個數列從第3項開始,每一項都等於前兩項之和。求大於輸入數的最小斐波那契數。

輸入格式: 在一行輸人一個正整數n(n>=10)。

輸出格式: 在一行輸出大於n的最小斐波那契數。

我的程式碼:

ls = [1 for x in range(1000)]
i = 2
n = int(input())
while 1:
print(ls[i])
if ls[i] > n:
print(ls[i])
break
else:
ls[i] = ls[i - 2] + ls[i - 1]
i += 1

我想建立一個長度為1000的列表,再將列表的數與n比較,得出符合的斐波那契數。

但是我發現當我通過ls = [1 for x in range(1000)]將ls初始化之後,列表的值無法改變,暫時沒有找到解決的辦法。

別人的程式碼:

n=int(input())
a=1
b=1
while a<=n:
a,b=b,a+b
print(a)

思考:

看了別人的程式碼才知道可以寫的這麼簡單,壓根就不用使用列表,只需要一個迴圈就可以解決了!可以學習的地方還有很多啊

以後我會多嘗試少使用列表,多用迭代的方式解決問題吧。

第四題:

第4章-13 求誤差小於輸入值的e的近似值 (20 分)

自然常數e可以用級數1+1/1!+1/2!+⋯+1/n!來近似計算。ei代表前i項求和。輸入誤差範圍error,當

ei+1-ei<error,則表示e的近似值滿足誤差範圍。

輸入格式: 在一行輸入誤差範圍。

輸出格式: 在一行輸出e的近似值(保留6位小數)。

我的程式碼:

s1 = -2.000000
s2 = 0.000000
num = 0
y = 1
n = float(input())
while s2 - s1 >= n:
j = 1
for x in range(1, y + 1):
j *= x
s1 = s2
s2 += 1 / j
y += 1
s2 += 1
print("%0.6f" % s2)

別人的程式碼:

error=float(input())
a,b,n=1,2,2
while b-a>=error:
a,b=b,b+(b-a)/n
n=n+1
print("%.6f"%b)

思考:

毫無疑問,別人的程式碼比我的簡潔太多太多了!

他把計算過程抽象成了一個簡單的公式a,b=b,b+(b-a)/n

而不需要像我那樣一個個求和,實在太厲害,他的數學一定很好。

第五題:

第4章-14 統計字元 (15 分) 本題要求編寫程式,輸入10個字元,統計其中英文字母、空格或回車、數字字元和其他字元的個數。

輸入格式: 輸入為10個字元。最後一個回車表示輸入結束,不算在內。

輸出格式: 在一行內按照

letter = 英文字母個數, blank = 空格或回車個數, digit = 數字字元個數, other = 其他字元個數

的格式輸出。

參考了別人的程式碼:

letter,blank,digit,other=0,0,0,0
s=input()
while 1:
for i in s:
if i.isalpha():
letter=letter+1
elif "0"<=i<="9":
digit=digit+1
elif i==" " or i=="\n":
blank=blank+1
else:
other=other+1
if letter+digit+blank+other>=10:
break
blank=blank+1
s=input()
print("letter = %d, blank = %d, digit = %d, other = %d"%(letter,blank,digit,other))

思考:

1.我一直在找python有沒有一種輸入函式可以把回車也讀取進去,但是卻找不到,因此也就不知道該怎麼寫。當我看到別人的程式碼之後發現其實根本就不必要一次性把全部字元都讀進去,這是問題的關鍵。

2.當沒有回車時,正常迴圈統計個數,當遇到回車後,只需要繼續進行input()輸入就行了,這裡就需要在外層再設定一個迴圈,當輸入的字元個數達到10個自動跳出迴圈,這是很關鍵的一個地方。