###### tags: `資訊科技` # 程式設計(使用Python、ZeroJudge) ## 零、評量、學習歷程 ### 1. 評量方式 + 上課基本練習(遲交期限:1週) **40%** + 作業題數 **20%** (期中10%+期末10%) - 作業登記表:[111](https://docs.google.com/spreadsheets/d/1hpB4g-NcoRz-dZlVrfguLCu8yWYpCy_TxcaCzAZRalE/edit?usp=drive_link) - [歷年作業登記表](https://hackmd.io/@cube/r1Cw2JgDT) - 每寫完一題作業,請將程式碼連結登錄於作業登記表,以統計作業題數。請小心不要改到別人的資料。惡意編刪別人的資料,視情節扣分或校規處理。 - 作業原始分數:解題數 $*$ 8 (最高120分) ``` if 上機考分數>=60 作業實得分數=作業原始分數 else 作業實得分數=作業原始分數*(上機考成績/60) ``` - 不要為了衝題數,做複製貼上、不求甚解這種沒意義的事。上機考0分,全部都寫也是0分。 - 不寫作業,除了無作業成績,上機考時網路會斷線,沒有任何參考資料,也必定寫不出來,請每個單元至少完成 3 題作業,熟練基本語法。**(不寫作業被當的機會很高,除非你有本事上機考2次都及格)** - 不要考前才寫作業,初學程式會有很多錯誤,要花時間除錯。請自我要求每週至少要寫 1 題作業,上機考才會比較保險。 - 不會的可以去參考網路上的程式碼、解法,同學也可以互相討論,而且是鼓勵的。不論如何,都要在了解解法後,不看別人的程式碼,自己親自寫一遍。 - 有做作業,考差了才有補救的機會,作業題為期末解題報告的題目。 + 期中上機考(迴圈教完後 1 週) **20%** + 期末上機考(倒數第 2 週) **20%** + 期末解題報告 **10%** - 非必要,想高分或不及格的同學請保握最後機會。 - 繳交期限:最後一週上課前 1 天。 - 分數:每一題 10 分。每個單元至多可放 2 題 (不可以都寫同一單元的題目) - 報告格式: * 第1頁為解題目錄(單元、題號、題目、頁碼)。 * 每題的子標題為 (1) 單元、題號、題目、題目簡述 (2) 解題動態、評分結果截圖 (3) 解題思路 (4) 程式碼 (5) 反思(遇到的錯誤、修正的地方、更好的方法…) (6) 錯誤程式碼 - 檢核方式: * 有交解題報告者,最後一週會請你在沒有網路的狀態下重寫一題當做檢核(題目由老師挑選),寫不出來作業直接作廢不算分,請務必自行思考完成。 * 不要為了分數直接複製貼上別人的程式碼,那是無意義的行為,檢核時你就會現出原形,就不用做這種白工了。 - 可整合上課內容後完成課程學習成果,上傳至學習歷程檔案平台。請儘量挑選一開始有錯,然後修正的題目,將修正的想法寫出來更能顯示出反思的能力。 + 如果對寫程式有興趣並要參加APCS檢定,下學期多元選修可以選修APCS(大學程式設計先修檢測)程式實作,挑選標準主要為ZJ的解題數(請寫在多元選修意向書裏)。 ### 2. [TOI推廣計畫-線上練習賽](https://tpmso.org/toi/index.php/reg/) + 成績計算:分數/100直接加在總成績。 + 上學期10、11、12月,下學期3、4、5月,最後一週。 + 星期一08:00 ~ 星期五20:00。90分鐘。 + [證書](https://drive.google.com/open?id=1DcgDKn1R33kOPc_HazdIyQDgyYxSCPlZ) ### 3. [APCS](https://apcs.csie.ntnu.edu.tw/) + 實作級分*2,直接加在總成績。 + 3級分免上機考,上機考成績為100。 + 4級分以上者,一切皆免,學期成績直接算100。 ### 4. 學習歷程檔案(修課記錄、課程學習成果) + 最後一週上課結束前如果認證完成,學期總成績加分。 + [撰寫「課程學習成果」參考資源](https://hackmd.io/@cube/HkCv90e19)。 ### 5. 基礎教學網站 + [Teach Python 3 and web design with 200+ exercises Learn Python 3 - Snakify](https://snakify.org/en/) + [tutorialpoint](https://www.tutorialspoint.com/python/index.htm) + [w3cschool](https://www.w3schools.com/python/) ### 6. Python APCS(中正大學 吳邦一教授) + [PythAPCS123講義](https://drive.google.com/drive/folders/1mnVdO2LHq7e4vesn6pt_R0-S6YWtz4Q4?fbclid=IwAR2Xo7LP8V3lWyhJEbFx3F8JLF9AIEI9t9snla9vwwtI4qlGc0mDwJVuf1o) + [PythAPCS123 YouTube撥放清單](https://youtube.com/playlist?list=PLpmg1QLbgMuSIDOgOcwf0Fbbn2ZDR7s-X ) + [PyApcs45 YouTube撥放清單](https://www.youtube.com/playlist?list=PLpmg1QLbgMuRQXHRkX9iDHyAVIW1D6OJF ) + [Python IDLE 完整安裝教學](https://simplelearn.tw/2022/07/30/python-%E4%BB%8B%E7%B4%B9%E5%8F%8A%E5%AE%89%E8%A3%9D%E6%95%99%E5%AD%B8-2022%E6%9B%B4%E6%96%B0%E7%89%88/) ### 7. 軟體 + [The collaborative browser based IDE - Replit](https://replit.com/) - 「+ Create Repl」 可新增一個 Repl (專案) - Template 欄選擇 「C++」 或 「Python (with Prybar)」,Title 欄填入專案標題如 a001, 再按「+ Create Repl」鈕,就會進入專案編輯的頁面。 - 如果 Template 沒有看到 Python (with Prybar) ,請自行輸入 prybar 後按「Search community templates」後點找到的「Python (with Prybar)」,按「+ Use Template」/「Use Template」,回首頁重新整理後,「Python (with Prybar)」即會出現在 「Favorites」項目下。 - My Repls:專案管理 New folder:建立分類資料夾,如 class、homework …。 專案.../Move:將專案移至分類資料夾。 - Themes:VS Code Dark/Use Theme - Indentation Size 調為4:側邊欄/Tools/User Settings/Indentation size:4。 - AI Code Completion:關閉。 + [GDB online Debugger | Compiler - Code, Compile, Run, Debug online C, C++](https://www.onlinegdb.com/) + [Online Python](https://www.online-python.com/) + [Google Colaboratory](https://colab.research.google.com/) + [Thonny](https://thonny.org/) (安裝套件: Tools/Manage plug-ins) ## 一、輸出與輸入、變數、運算式與運算子 ### 1. 輸出與輸入 + 變數=input(\[提示字串\]) + print(項目1\[,項目2,...\]) - 字串要加 '&nbsp;&nbsp;' 或 "&nbsp;&nbsp;" - 可用 + 將字串連接 - print() 輸出後,預設會自動補上換行符號。 - 印出多個項目,預設以一個空白間隔。 ``` python print('Hello Python') # 印出一段文字 print('Hello', 'Python', 123) # 印出多個項目,預設以一個空白間隔 print('Hello', 'Python', 123, sep=',') # 以『,』為項目間的分隔符號 ``` + print('A=%d B=%d C=%d' %(A, B, C)) - [Python 3 print 函数用法总结](http://www.runoob.com/w3cnote/python3-print-func-b.html) + print('A={} B={} C={}'.format(A, B, C)) - {} 的位置會被後方 format 所帶的參數所取代,預設會依照順序輸出。 - [Python Format String 字串格式化整理](https://blog.jaycetyle.com/2018/01/python-format-string/) + print(f'A={A} B={B} C={C}') - [f-string 是 Python 3.6 才有的方法](https://myapollo.com.tw/blog/python-f-string-formating-syntax/#google_vignette) :::info EX_1_1:[d483: hello, world](https://zerojudge.tw/ShowProblem?problemid=d483) + Replit 快速鍵 `Ctrl+Enter`:執行目前程式 `Ctrl+a`:全選 `Ctrl+c`:複製 `Ctrl+v`:貼上 `Ctrl+x`:剪下 `Ctrl+Shift+v`:Replit 測資貼上。或右鍵/貼上。 `Ctrl+滾輪`:放大、縮小 + Thonny 快速鍵 `F5`:執行目前程式 ::: :::info EX_1_2:[a001: 哈囉](https://zerojudge.tw/ShowProblem?problemid=a001) ``` python s=input() print('hello,',s) # EOF 結尾的測資 while True: try: s=input() print('hello,',s) except: break ``` + 快速鍵 `Shift`+方向鍵、`Home`、`End`:選取程式 + Python 以冒號「:」及縮排來表示程式區塊。 - if、else、elif、for、while 等為會使用到程式區塊的關鍵字,在其「:」之後的下一行的就必須縮排。 - 以`Tab`鍵縮排,之前已先調整為4個空白。 ::: ### 2. 變數與資料型態 + 變數:存放資料的記憶體空間(名稱自訂) + 數值型態:int(整數)、float(浮點數、小數)、bool(True、False) + 字串型態:'&nbsp;&nbsp;' 或 "&nbsp;&nbsp;" 中的文字 + 容器型態: - list:有順序、可變動的資料集合 - tuple:有順序、不可變動的資料集合 - set:無順序的資料集合 - dict:鍵值對(key-value)的集合 + 等號的意義是『賦值』(assignment),不是『等於』,把等號右邊計算完的值指定給等號左邊的變數(左邊一定是變數(記憶體位置))。 - 錯誤:a+5=7 - a,b=1,2 + 資料型態轉換:int()、float()、str() - int(): 字串或浮點數轉整數 - str(): 數字轉字串 - float(): 字串轉浮點數 :::info EX_1_3:[d049: 中華民國萬歲!](https://zerojudge.tw/ShowProblem?problemid=d049) ``` python s=input() # 讀入的為字串 y=int(s) # 將字串轉換為整數,整數才能做算數運算加減乘除 y=int(input()) # 上兩行整合 y=int(input('please input y:')) # 可以輸出一段訊息再讀入,但OJ不能用(OJ不可輸出規定以外的東西)。 ``` ::: :::info EX_1_4:[a002: 簡易加法](https://zerojudge.tw/ShowProblem?problemid=a002) + 同一行輸入兩個整數(空白間隔) - a, b = map(int, input().split()) - str.split() 可將 str 字串分割成數個子字串(以空白區分) - map(某函式名, list) 會把某函式依次作用到list的每個元素上 ::: :::info EX_1_5:[d489: 伏林的三角地](https://zerojudge.tw/ShowProblem?problemid=d489) + 以[海龍公式](https://zh.wikipedia.org/zh-tw/%E6%B5%B7%E4%BC%A6%E5%85%AC%E5%BC%8F)求三角形面積。 + 「*」不可省略。 + 先乘除後加減,可用小括號改變運算順序。 + 浮點數與整數運算後會變成浮點數,整數做『/』運算後也會變成浮點數。在OJ上,答案36.0與36是不一樣的,要注意輸入、輸出的說明。 ::: :::warning [a861: 1. Secure the Perimeter](https://zerojudge.tw/ShowProblem?problemid=a861) + EOF 結尾的測資 ``` python while True: try: ~ ~ except: break ``` ::: :::warning [d461: 班際籃球賽](https://zerojudge.tw/ShowProblem?problemid=d461) ::: :::warning [d053: 10970 - Big Chocolate](https://zerojudge.tw/ShowProblem?problemid=d053) + EOF 結尾的測資 ``` python while True: try: ~ ~ except: break ``` ::: ### 3. 算數運算子 | 算數運算子 | 意義 | 備註| |:-------- |:------ |:-------| | + | 加 | | | - | 減 | | | * | 乘 | | | / | 除 |17/5 為 3.4,15/5 為 3.0 | | // | 取商數 |17//5 為 3</br> 17.0//5 為3.0 | | % | 取餘數 |17%5 為 2 | | ** | 次方 | 5**2 為 25 | :::info EX_1_6:[d050: 妳那裡現在幾點了?](https://zerojudge.tw/ShowProblem?problemid=d050) + 取餘數:% + [常用運算子的優先順序](https://sites.google.com/site/jingprogrampy/python/%E9%81%8B%E7%AE%97%E5%AD%90%E9%81%8B%E7%AE%97%E5%BC%8F) ::: :::info EX_1_7:[d485: 我愛偶數](https://zerojudge.tw/ShowProblem?problemid=d485) + 將 a 調整為後一個偶數, b 為前一個偶數,[計算等差數列項數](https://zh.wikihow.com/%E8%AE%A1%E7%AE%97%E7%AD%89%E5%B7%AE%E6%95%B0%E5%88%97%E4%B8%AD%E7%9A%84%E9%A1%B9%E6%95%B0)。 + a 偶數 a=a+0,a 奇數 a=a+1 - a=a+a%2 + 複合指定運算子(a=a+5 → a+=5) + 整數除法:// ::: :::info EX_1_8:[d051: 糟糕,我發燒了!](https://zerojudge.tw/ShowProblem?problemid=d051) + c=(f-32)*5/9 + 小數點位數控制。 print(f'{c:.3f}') ::: :::warning [d073: 分組報告](https://zerojudge.tw/ShowProblem?problemid=d073) + 整數除法:// ::: :::warning [c379: 成為出題者](https://zerojudge.tw/ShowProblem?problemid=c379) + 整數除法:// ::: :::warning [d827: 買鉛筆](https://zerojudge.tw/ShowProblem?problemid=d827) + 整數除法:// + 取餘數:% ::: :::warning [b757: 頸美椰子樹](https://zerojudge.tw/ShowProblem?problemid=b757) + 除:/ + %g 根據數值大小採用 %e 或 %f。 + %g 如果小數點為0,不會輸出。 ::: :::warning [a862: 2. My Dear Friend VIR](https://zerojudge.tw/ShowProblem?problemid=a862) + 除:/ + 小數點位數控制。 + EOF 結尾的測資。 ``` python while True: try: ~ ~ except: break ``` ::: :::warning [f651: 開關燈](https://zerojudge.tw/ShowProblem?problemid=f651) + 整數除法:// + 觀察n=1~10,找規律。類似d073。 + EOF 結尾的測資。 ``` python while True: try: ~ ~ except: break ``` ::: ### 4. 關係運算子 | 關係運算子 | 意義 | 備註| |:-------- |:------ |:-------| | == | 等於 | =是賦值,==是判斷是否相等 | | != | 不等於 || | > | 大於 || | >= | 大於等於 || | < | 小於 || | <= | 小於等於 || :mega: python 可以用 1 < x < 9 ,其它語言不行,該如何? 1<x and x<9 ### 5. 邏輯運算子 | 邏輯運算子 | 意義 | 備註| |:-------- |:---- |:---| | and | 而且 || | or | 或者 || | not | 否 || :::info EX_1_9:[d063: 0 與 1](https://zerojudge.tw/ShowProblem?problemid=d063) + not ::: :::info EX_1_10:[e343: BMI 計算](https://zerojudge.tw/ShowProblem?problemid=e343) + 輸入分兩行讀入。 + 字串轉浮點數。 + 運算式中沒有中、大括號,通通都用小括號。 + 次方:** ::: ## 二、選擇 ### 1. if 條件式語法 ``` python if 條件: 條件「成立」時的程式碼 ``` :mega: if 後要加「:」 :mega: python 沒有如 C++ 的大括號 { } 來表示程式區堆,沒縮排、縮排錯誤都會有問題。 :::info EX_2_1:[a012: 10055 - Hashmat the Brave Warrior](https://zerojudge.tw/ShowProblem?problemid=a012) + Q:以下的程式會發生什麼問題? ``` python if ans<0: ans=-ans print(ans) ``` ::: :::warning [a799: 正值國](https://zerojudge.tw/ShowProblem?problemid=a799) ::: :::warning [d068: 該減肥了!](https://zerojudge.tw/ShowProblem?problemid=d068) ::: :::warning [b682: 2. 同學早安](https://zerojudge.tw/ShowProblem?problemid=b682) + [提示](https://zerojudge.tw/ShowThread?postid=16450&reply=0) + 將時間全部轉成分鐘會比較好做,分鐘的時間差以//、%轉回小時、分。 + 因為校長最久只會站23小時59分,所以如果開始時間大於結束時間,表示站隔夜,結束時間要多加1440。 ::: ### 2. if~else 語法 ``` python if 條件: 條件「成立」時的程式碼 else: 條件「不成立」時的程式碼 ``` :mega: 側邊欄/Tools/User Settings/Indentation Detection:Automatically detect indentation settings when opening a file. 或許可讓 else 自動對齊 if :mega: else:後面不要寫條件。 :::info EX_2_2:[d064: ㄑㄧˊ 數?](https://zerojudge.tw/ShowProblem?problemid=d064) ::: :::info EX_2_3:[d066: 上學去吧!](https://zerojudge.tw/ShowProblem?problemid=d066) + if h>=7 and m>=30 and h<17: → 幾點會造成錯誤? + if (8<=h<17) or (7點的狀況): + and、or + [常用運算子的優先順序](https://sites.google.com/site/jingprogrampy/python/%E9%81%8B%E7%AE%97%E5%AD%90%E9%81%8B%E7%AE%97%E5%BC%8F) ::: :::warning [b877: 我是電視迷](https://zerojudge.tw/ShowProblem?problemid=b877) ::: :::warning [f373: 週年慶 Anniversary](https://zerojudge.tw/ShowProblem?problemid=f373) + 分別計算兩百貨折扣後的金額,比較大小輸出。 ::: :mega: 如果測資的第一行有一個整數t,代表測試的筆數,要用以下的寫法。 ``` python t=int(input()) for _ in range(t): ~ # 輸入 ``` :::warning [e948: 1. 基礎代謝率 (BMR Calculation)](https://zerojudge.tw/ShowProblem?problemid=e948) + 輸入的第一行有一個整數n,代表測試筆數。 ::: :::warning [f043: 1. 小豪的回家作業 (Homework)](https://zerojudge.tw/ShowProblem?problemid=f043) + 給定兩整數R、A,求出A+B=R的B值後輸出。 + 如果R=A,則先將A-3再求B。 + A、B小的寫在算式的前面。 ::: ### 3. 巢狀 if 語法 ``` python if 條件1: if 條件2: 條件1「成立」,且條件2「成立」時的程式碼 else: 條件1「成立」,且條件2「不成立」時的程式碼 else: 條件1「不成立」時程式碼 ``` :mega: if 或 else 的程式區塊內,都可再增加條件式。 :::info EX_2_4:[d058: BASIC 的 SGN 函數](https://zerojudge.tw/ShowProblem?problemid=d058) + if n>0: vs. if n>=0: ::: :::info EX_2_5:[a006: 一元二次方程式](https://zerojudge.tw/ShowProblem?problemid=a006) + 開根號可用**0.5 + 註解:\# + d==0時,x1還是要計算過程。執行時,不會去執行不符合條件的程式碼。 + Q:x1、x2放在d後面計算可以嗎?負數開根號? + 需除錯時,可直接在Console視窗詢問變數內容,或將變數印出來看。 + 示範「除錯目前程式」看程式執行流程。 + [Python f-string 各種格式使用方法](https://myapollo.com.tw/blog/python-f-string-formating-syntax/#google_vignette) ::: :::warning [a003: 兩光法師占卜術](https://zerojudge.tw/ShowProblem?problemid=a003) ::: :::warning [d065: 三人行必有我師](https://zerojudge.tw/ShowProblem?problemid=d065) ::: :::warning [f165: 棒棒糖事件](https://zerojudge.tw/ShowProblem?problemid=f165) + 判斷棒棒糖數除以小朋友人數的餘數r是否為0,當r=0時,輸出「OK!」,反之輸出r。 + 小朋友人數可能為0,不會搶成一團,所以蝸牛老師不需吃下任何棒棒糖,輸出「OK!」。 + 先排除小朋友人數為0的狀況,不然「%」運算會錯誤。 ::: :::warning [b899: 2. 物品探測](https://zerojudge.tw/ShowProblem?problemid=b899) + 分別計算三點間的距離,最長的為正方形的對角線。 + 正方形四點 A、B、C、D,假設 A、C 為對角,則 D = A + C - B。 ::: ### 4. 多重選擇 if\~elif\~else 語法 ``` python if 條件1: 條件1「成立」時程式碼區塊 elif 條件2: 條件1「不成立」,且條件2「成立」時的程式碼 elif 條件3: 條件1、2「不成立」,且條件3「成立」時的程式碼 ... else: 上述條件都「不成立」時的程式碼 ``` :mega: else if()可視需要增加。 :::info EX_2_6:[d460: 山六九之旅](https://zerojudge.tw/ShowProblem?problemid=d460) + if a>=0 and a<=5: # 輸入有規定 0≤a≤2147483647,所以不用寫 a>=0 ::: :::warning [f337: 同樂會 (Party)](https://zerojudge.tw/ShowProblem?problemid=f337) ::: :::warning [b676: 63萬勞工苦輪班不像人像機器](https://zerojudge.tw/ShowProblem?problemid=b676) ::: :::warning [a053: Sagit's 計分程式](https://zerojudge.tw/ShowProblem?problemid=a053) ::: :::warning [c382: 加減乘除](https://zerojudge.tw/ShowProblem?problemid=c382) + 先不要使用 eval(),練習多重選擇。 + 輸入使用split()先分割就好,要計算時再轉成int。 ::: ## 三、迴圈 ### 1. range 函式 + 串列變數=range(整數) - 產生0~「整數-1」的串列 + 串列變數=range(起始值,終止值) - 產生起始值~「終止值-1」的串列 - 左閉右開區間 + 串列變數=range(起始值,終止值,間隔值) - 產生:起始值, 起始值+間隔值, 起始值+間隔值*2, ... + [Python range() 函数用法](http://www.runoob.com/python/python-func-range.html) ### 2. for 迴圈語法 ``` python for 變數 in range(重複次數): 程式碼 ``` ``` python for 變數 in 串列: 程式碼 ``` ``` python for 變數 in 字典: # 變數會儲存字典的key 程式碼 ``` ``` python break:強制跳出「整個」迴圈 continue:強制跳出「此次」 迴圈,繼續進入下一次圈 ``` ``` python for 變數 in 串列或字串: 程式碼 else: 迴圈正常結束,執行此區塊程式碼。(break不會執行) ``` :mega: 逐行除錯 [Replit](https://docs.replit.com/programming-ide/workspace-features/debugging) (1) 執行目前程式(Ctrl+Enter)後發現錯誤。 (2) 打開除錯視窗(Debugger),並將其拖曳至適當位子(不要和Console在同一窗格)。 (3) 設定中斷點(可跳過沒問題的程式)。 (4) 按除錯視窗的『RUN』。 (5) 使用『Next Step』或『Skip Step』或『Next Breakpoint』逐行執行,並觀察變數的變化。 (6) 發現錯誤按『Stop』停止除錯,修正程式。 Thonny (1) 執行目前程式(F5)後發現錯誤。 (2) 設定中斷點(可跳過沒問題的程式)。 (3) 除錯目前程式(開始逐行執行)。 (4) 檢視/變數,開啟變數面板,可以看到執行每一步的變數變化。 (5) 使用『跳過(Step Over)(F6)』或『跳入(Step into)(F7)』逐行執行。 (6) 發現錯誤後按『STOP』停止除錯,修正程式。 :::info EX_3_1:[d498: 我不說髒話](https://zerojudge.tw/ShowProblem?problemid=d498) + 迴圈變數名:i 或 _ + [字串中輸出單引號](https://blog.csdn.net/menghuanshen/article/details/104289192) + 練習「除錯目前程式」看迴圈執行流程。 ::: :::info EX_3_2:[d491. 我也愛偶數 (swap 版)](https://zerojudge.tw/ShowProblem?problemid=d491) + Q:先完成 a+...+b,會有錯誤? A:sum 初值要歸零。雖然python變數不需要事先宣告,但它沒厲害到可以沒初值,就直接放在表達式中去進行運算(沒有賦值會不知道該變數是什麼類型,預設為'內建函數或方法',因而無法判斷能否進行運算) + python 兩變數交換:a,b=b,a + C不能這樣寫 ``` c t=a; a=b; b=t; ``` ::: :::info EX_3_3:[h658: 捕魚 (Fishing)](https://zerojudge.tw/ShowProblem?problemid=h658) + min_d(最小距離)的初值可假設為一個比可能最大值還要大的值(如1000)。 + 開根號可用**0.5,d=((x-a)\**2+(y-b)\**2)**0.5 + 讀入每個魚群的中心座標(a,b),計算魚夫和魚群的距離,如果比目前的最小距離小,則記錄此時的最小距離和座標(min_a,min_b)。 ::: :::warning [b970: 我不說髒話 (續)](https://zerojudge.tw/ShowProblem?problemid=b970) + range範圍 + 數字和『.』中間沒有空白。 ::: :::warning [a244: 新手訓練 ~ for + if](https://zerojudge.tw/ShowProblem?problemid=a244) ::: :::warning [f338: 后羿射日(Archer)](https://zerojudge.tw/ShowProblem?problemid=f338) + 距離用 R**2,不需開根號。 ::: :::warning [f605: 1. 購買力](https://zerojudge.tw/ShowProblem?problemid=f605) + 找出3物品最大值和最小值,可使用max、min函式。 ::: :::warning [f312: 1.人力分配](https://zerojudge.tw/ShowProblem?problemid=f312) + 以for迴圈枚舉所有可能的工人分配方法。 + 求最大值可用max函式或if。 ::: ### 3. list 簡介 + list(串列) 把很多元素串起來,依照排列的順序給予編號 0, 1, 2,... ``` python a=[3,5,7,1,2] print(a) print(a[2]) for n in a: print(n) # 每印一個元素換行 for n in a: print(n, end=' ') # 每行以空白結尾 for i in range(len(a)): # 以索引值存取 print(a[i]) print(*a) # 印出每個元素。「*」可將序列分解成多個獨立的元素(不在賦值語句中使用*號) print(*a, sep=',') # 可以更改分隔符號 ``` + list常用的計算函式 | 串列函式 | 意義 | |:------------ |:-------------- | | lst=list() 或 lst=[] |宣告空的串列| | len(lst) | 回傳串列個數 | | max(lst) | 回傳串列中的最大值 | | min(lst) | 回傳串列中的最小值 | | sum(lst) | 將串列元素加總 | + 運用 [] 取值,可以使用 index(索引值從0開始)、slice 來存取陣列裡的資料。假設lst,lst2為串列變數,常用的運算和方法如下表 | slice運算 | 意義 | |:----------- |:-------------- | | lst[i] | 取出索引值i的元素 | | lst[-1] | 取出最後一個元素 | | lst[i:j] | 取出索引值i~j-1的元素 | | lst[i:j:k] | 取出索引值i~j-1的,間隔為k的元素 | | lst[i:j]=lst2| 把索引值i~j-1的元素換成lst2的元素 | | del lst[i:j] | 刪除索引值i~j-1的元素 | :::info EX_3_4:[j178: 手遊廣告 (Advertisement)](https://zerojudge.tw/ShowProblem?problemid=j178) + 同一行輸入兩個整數(空白間隔) - m, a = map(int, input().split()) + 同一行的多個元素轉成 list (元素個數可不定) - val = [*map(int,input().split())] - val = list(map(int,input().split())) - val = [int(x) for x in input().split()] # 使用列表生成式(list comprehension),將讀進來的字串轉成整數後放入一個list。 + Q:如果寫成以下的程式什麼樣的測資會錯誤? ``` python for t in val: if a>t: a+=t ``` + 迴圈中斷 - break:強制跳出「整個」迴圈。 - continue:強制跳出「此次」 迴圈,繼續進入下一次圈。 ``` python for i in range(10): if i==5: break # continue print(i) ``` ::: <font color="#fff">A:3 10</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5 10 20 10</font> :::info EX_3_5:[f708: 蟲蟲危機 (Insect)](https://zerojudge.tw/ShowProblem?problemid=f708) + 串列元素加總 ``` python val=[1,2,3] sum=0 for t in val: sum+=t print(sum) ``` + sum(lst) 將串列元素加總 ::: :::info EX_3_6:[c299: 1. 連號或不連號](https://zerojudge.tw/ShowProblem?problemid=c299) + 輸入數列時,找出其最大值和最小值,可使用if或max、min函式。 ``` python val=[2,1,4,3] mx=0 # 初值設一個極小值 for t in val: if t>mx: mx=t print(mx) ``` + 最大-最小+1==n,表示這個數列是連續的。 + max()、min() + [] slice取值 + 三元運算子 ``` python if a>b: ans=a else: ans=b ans=a if a>b else b ``` ::: :::warning [d046: 文文採西瓜](https://zerojudge.tw/ShowProblem?problemid=d046) ``` python watermelon = [*map(int,input().split())] watermelon = list(map(int,input().split())) watermelon = [int(x) for x in input().split()] ``` ::: :::warning [b138: NOIP2005 1.陶陶摘苹果](https://zerojudge.tw/ShowProblem?problemid=b138) ::: :::warning [f063: The Strongest Chain](https://zerojudge.tw/ShowProblem?problemid=f063) + 求每條鏈子最小值中,找出最大值。 + max()、min() + [] slice取值 + abs() 取絕對值 ::: :::warning [c290. APCS 2017-0304-1秘密差](https://zerojudge.tw/ShowProblem?problemid=c290) + line = [int(x) for x in input()] # 把每一個數字字元轉換成整數後存入list + [] slice取值 ::: ### 4. 巢狀迴圈語法 + Q:在日常生活中,有什麼事像巢狀迴圈的概念? ``` python for i in range(外圈次數): for j in range(內圈次數): 程式碼 ``` + 九九乘法表 ``` python for i in range(1, 10): for j in range(1, 10): print(f'{i}x{j}={i*j}', end=' ') # end=' ' 表示每行以空白結尾 print() # 內層迴圈執行結束後才換行 ``` :::info EX_3_7:[e621. 1. 免費停車 (Free Parking)](https://zerojudge.tw/ShowProblem?problemid=e621) + 布林型態(True、False):free = False + 免費停車位以空白隔開,輸出一筆之後才以print()換行。 ::: :::info EX_3_8:[d660: 11764 - Jumping Mario](https://zerojudge.tw/ShowProblem?problemid=d660) + wall= [*map(int,input().split())] + 用 now 表示目前高度,每次和右牆比較完,調整其為右牆的高度。 + for w in wall[1:]: # wall[1:]索引值留白表示取到最後一個 ::: :::warning [d786: 三、平均值](https://zerojudge.tw/ShowProblem?problemid=d786) + 每筆測資sum要歸零。 + 每筆輸入 num=[*map(int,input().split())] + n=num[0]為數列長度。 + 加總num[1]~num[n]後平均。 - for x in num[1:]: - print(f'{sum/n:.2f}') ::: :::warning [c005: 10300 - Ecological Premium](https://zerojudge.tw/ShowProblem?problemid=c005) + 每筆測資獎金要歸零。 + 運算式可先化簡避免除法誤差。 ::: :::warning [c013: 00488-Triangle Wave](https://zerojudge.tw/ShowProblem?problemid=c013) + _ = input() # 第一列和測資間有一空白行要讀掉 + 下半部 for j in range(A-1, 0, -1): + 印出數字不換行 print(j, end='') + 換行 print() ::: ### 5. while 迴圈語法 ``` python while 條件判斷: # 條件為「真」的時候繼續執行 程式碼 ``` :::info EX_3_9:[d189: 11150 - Cola](https://zerojudge.tw/ShowProblem?problemid=d189) + 請用 while 模擬換瓶過程,不可以直接套公式。 + 以除錯看換瓶過程,最後剩 2 空瓶,可借 1 空瓶多換 1 瓶。 + 整數除法:// ``` python= ~ sum=n while ~: ~ # 可以新換幾瓶 ~ # 更新空瓶數量,新換+換剩的 if n==2: sum+=1 print(sum) ``` + 題目先借瓶,什麼狀況需要借? → 不管需不需要都借。為什麼 n=9 時,不需要借也借,卻不會錯誤。(除錯) ``` python= sum=n n+=1 while ~: ~ ``` ::: :::info EX_3_10:[a215: 明明愛數數](https://zerojudge.tw/ShowProblem?problemid=a215) + m 可能小於 0,while 迴圈連1次都不會進入。 + 方法一:m<0 直接輸出 1 + 方法二:whilt True: + break ::: :::warning [c079: 10346 - Peter's Smokes](https://zerojudge.tw/ShowProblem?problemid=c079) + 類似 d189 ::: :::warning [d570: 神龍見首不見尾](https://zerojudge.tw/ShowProblem?problemid=d570) ::: :::warning [d356: NOIP2002 1.级数求和](https://zerojudge.tw/ShowProblem?problemid=d356) ::: :::warning [f070: 1. 韓信點兵 (HanXin)](https://zerojudge.tw/ShowProblem?problemid=f070) + 因為答案很小,暴力解即可。 + 以 while 迴圈,從1開始測,輸出符合條件的值。 ::: :::warning [c350: “綠白黃” 四校聯課](https://zerojudge.tw/ShowProblem?problemid=c350) + ans+=(n/k)*w # 每次新換的電話號碼 + n-=(n/k)*(k-w) # 因為 k > w,所以可以看成每一次的交換(k換w),新號碼會減少 (k-w) 個 ::: ## 四、複合式資料型態 ### 1. [list(串列)](https://www.twblogs.net/a/5cd7d860bd9eee67a77f8884) + 串列變數 = [ 元素1, 元素2, .... ] # 類似 C 的「陣列」。 + 串列b = 串列a,不同於變數,不是將 a 複製到 b,兩者會有相同的記憶體位置。c = a.copy() 才會將 a 複製給 c。 ``` python a = [ 1, 2, 3] b = a b[2] = 5 print(a,b) c = a.copy() c[2]=7 print(a,c) ``` + 列表對「+」和「$*$」的操作與字串相似。「+」用予組合列表,「$*$」用於重複列表。 | 串列運算 | 範列 | |:-------- |:-------------- | | + |[1, 2]+[3, 4]為[1, 2, 3, 4]| | $*$ |[1, 2]\*3為[1, 2, 1, 2, 1, 2]| | x in lst |判斷x是否在串列, 3 in [1, 2, 3]為True| | == |判斷兩串列是否相等, [1, 2]==[1, 2, 3]為False| + 運用 [] 取值,可以使用 index(索引值)、slice 來存取陣列裡的資料。 - 編號由0開始。 - 區間定義都是左閉右開(不含右端)。 - 負的編號是倒數,最後一個是-1。 - 第一個編號不寫代表開頭,第二個編號不寫表示一直到結尾都包含。 - 完整的 slice 包含 list[start,stop,step],step 表示每次增加幾個位置,step=-1 會反轉 list。 | slice運算 | 意義 | |:------------ |:-------------- | | lst[i] | 取出索引值i的元素 | | lst[-1] | 取出最後一個元素 | | lst[i:j] | 取出索引值i~j-1的元素 | | lst[i:j:k] | 取出索引值i~j-1的,間隔為k的元素 | | lst[i:j]=lst2| 把索引值i~j-1的元素換成lst2的元素 | | del lst[i:j] | 刪除索引值i~j-1的元素 | ``` python lst = [0, 1, 2, 3, 4, 5] lst[ :4:2] lst[ : :3] lst[ : :-1] lst[ 2: :-1] # 從 idx 2 開始反向走到頭 ``` + 常用串列函式 | 串列函式 | 意義 | |:------------ |:-------------- | | lst=list() 或 lst=[] |宣告空的串列| | len(lst) | 回傳串列個數 | | max(lst) | 回傳串列中的最大值 | | min(lst) | 回傳串列中的最小值 | | list('abc') | 將'abc'拆成'a','b','c'加入串列 | | 串列方法(函式) | 意義 | |:---------------|:-------------- | | lst.append(x) | 將x附加到串列後面 | | lst.insert(i,x)| 將x插入到索引值i的位置 | | lst.extend(x) | 將串列x中的所有元素,附加到串列後面。<br />a=[1,2] b=[3,4] <br /> a.append(b) vs. a.extend(b)| | lst.remove(x) | 刪除串列中的第一個x | | lst.pop(i) | 回傳索引值i的元素,並將其刪除;<br/>如果沒有i,則傳回最後一個元素並刪除 | | lst.index(x) | 回傳第一次出現x的索引值 | | lst.count(x) | 計算出現x的次數 | | lst.sort() | 將串列中的元素小->大排序,大->小則加入參數reverse=True | | lst.reverse() | 將串列中的元素反轉 | | lst2=lst.copy()| copy串列 | | lst.clear() | 清除串列內所有元素 | + [列表生成式(List Comprehensions)](https://www.liaoxuefeng.com/wiki/1016959663602400/1017317609699776), 類似數學集合的表示法。$\{ 2n+1 \mid n \in \{0, 1, 2, 3, 4\} \} \rightarrow \{1,3,5,7,9\}$ - 以說明 list 內容的方式建構 list,把 for 迴圈包含在 list 建構中,可以是巢狀迴圈,甚至加 if 來過濾。 ``` python a = [] for i in range(5): a.append(2*i+1) a = [ 2*i+1 for i in range(5)] b = [ x for x in a if x%3==0] # [3, 9] ``` :::info EX_4_1:[g595. 1. 修補圍籬](https://zerojudge.tw/ShowProblem?problemid=g595) + 對於每一個 0,把它左右較小的數字取出加總 + 左右邊界如果是 0,要特別處理,因為左邊界只有右邊鄰居而右邊界只有左邊鄰居。 ::: :::info EX_4_2:[b558: 求數列第 n 項](https://zerojudge.tw/ShowProblem?problemid=b558) + append() ::: :::info EX_4_3:[a693: 吞食天地](https://zerojudge.tw/ShowProblem?problemid=a693) + 每次都重算會TLE。 + [時間複雜度](https://jason-chen-1992.weebly.com/home/time-space-complexity) + [前綴和](https://www.youtube.com/watch?v=VfL7dzFkW30),不要用爆力法 ``` python for i in range(1,n+1): # 對每個idx for j in range(1,i+1): # 從頭開始加到此idx pfx[i]+=food[j] ``` + i=0時,pfx[i]=pfx[i-1]+food[i] 會錯誤,所以改從index 1 開始放前綴和。 - [1-based indexing](https://xlinux.nist.gov/dads/HTML/oneBasedIndexing.html) - food=[0]+[*map(int,input().split())] ::: :::info EX_4_4:[i071: 風景 (Landscape)](https://zerojudge.tw/ShowProblem?problemid=i071) + [1-based indexing](https://xlinux.nist.gov/dads/HTML/oneBasedIndexing.html) + 從小明家往左、往右檢查>小明家樓高的數量,錯誤的原因為? + 以變數(LMax、RMax)記錄小明家左邊、右邊最高樓高(初值為小明家樓高)。從小明家往左、往右檢查,如果檢查的樓高>LMax、RMax,則答案+1,並調整LMax、RMax。 + 或往右發現有比小明家高的樓高,就讓小明家長高。(小明家高要先保留,往左檢查前要恢復原高) + slice + 變數名儘量小寫, rMax 和 RMax是不同的,且因為變數不用宣告,迴圈內如果打錯也不知道。 ::: :::info EX_4_5:[b139: NOIP2005 2.校门外的树](https://zerojudge.tw/ShowProblem?problemid=b139) + 可以宣告一個整數串列tree(預設為1),索引值代表位置,值0、1表示有沒有樹。 ::: :::warning [b127: 會議中心(Room)](https://zerojudge.tw/ShowProblem?problemid=b127) + [費式數列](https://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97) + [0]*50 ::: :::warning [f818: 物競天擇 (Survival)](https://zerojudge.tw/ShowProblem?problemid=f818) + 設一個變數存身高*體重的最小值,初值為1000005。 + 進階可以使用 zip - [python多個變數的for迴圈](https://www.itread01.com/content/1544266142.html) - [Python zip()函數](http://www.runoob.com/python3/python3-func-zip.html) - for h,w in zip(height, weight) ::: :::warning [e339: 前綴和練習](https://zerojudge.tw/ShowProblem?problemid=e339) + 小心不要出現pfx[-1]的狀況。 ::: :::warning [a253: 王老先生的磨菇田](https://zerojudge.tw/ShowProblem?problemid=a253) + 因為蘑菇編號只介於0~100間,因此可以開一個大小為101的陣列(初始值皆為0),陣列的索引值代表蘑菇編號,儲存對應編號的蘑菇數量。 ::: :::warning [b374: [福州19中]众数](https://zerojudge.tw/ShowProblem?problemid=b374) + [想法參考](https://zerojudge.tw/ShowThread?postid=16300&reply=0) ::: :::warning [c199: 爬山去(Hiking)-TOI練習賽y7m5-1](https://zerojudge.tw/ShowProblem?problemid=c199) + 輸入時可先將重覆的數字去掉。 ::: :::warning [g308: pB. 跳跳布朗尼(Brownie)](https://zerojudge.tw/ShowProblem?problemid=g308) + 使用布林陣列來記錄每個格子是否普經走過。 + 亦可直接使用記錄「傳送點資訊」的陣列,走過就設為「-1」。 ::: ### 2. list of list + list 中元素可以是不同型態,也可以放list。所以二維矩陣由 list of list 實作。 ``` python lst = [1,'apple',[1,2,3]] a = [ [1, 2, 3], [4, 5, 6] ] for i in range(2): # 列 for j in range(3): # 欄 print(a[i][j],end=' ') print() ``` | a[0][0] | a[0][1] | a[0][2] | | -------- | -------- | -------- | |**a[1][0]**|**a[1][1]**|**a[1][2]**| + 使用列表生成式產生2維以上串列 ``` python a = [ [0 for i in range(3)] for j in range(2) ] # lst=[[0, 0, 0], [0, 0, 0]] a = [ [0]*3 for i in range(2)] # 初始化一個2*3矩陣,初值均為 0 b = [[0]*4]*3 # 錯誤! Why? b[1][1]=5,看會印出什麼? c = [[1,2,3]]*2 # 等於 c[0]=[1,2,3]; c[1]=c[0] ``` :::info EX_4_6:[e798: p5. 卷積神經網路](https://zerojudge.tw/ShowProblem?problemid=e798) + 多行輸入 ``` python a = [] for _ in range(n): a.append([*map(int, input().split())]) a = [[] for i in range(n)] for i in range(n): a[i] = [*map(int, input().split())] a = [ [*map(int, input().split())] for _ in range(n)] ``` + 求最大值可用max函式或if。 ::: :::info EX_4_7:[a694: 吞食天地二](https://zerojudge.tw/ShowProblem?problemid=a694) + 前綴和 ![](https://hackmd.io/_uploads/r1vpzDlSn.png) **➜** ![](https://hackmd.io/_uploads/BJMRGvlr3.png) + [如何以a693的方式加速?](https://sites.google.com/a/mail.hpsh.tp.edu.tw/pc/jiao-cai/a694-tun-shi-tian-de-er) |[0][0] |[0][1]|[0][2] |[0][3] |[0][4]|[0][5] | |:----: |:----:|:----: |:----: |:----:|:----: | |**[1][0]**| | | | | | |**[2][0]**| |[r1-1][c1-1]| | |[r1-1][c2]| |**[3][0]**| | |[r1][c1]| | | |**[4][0]**| | | | | | |**[5][0]**| |[r2][c1-1] | | |[r2][c2] | ::: :::info EX_4_8:[f513: 舉旗遊戲 (Flag)](https://zerojudge.tw/ShowProblem?problemid=f513) + 如果自己的顏色和相鄰 8 點都不同,則淘汰人數+1。 + 先定義每一個方向列、欄的差值 dr=[-1, -1, -1, 0, 0, 1, 1 ,1] dc=[-1, 0, 1, -1 ,1 ,-1 ,0 ,1] + (進階)for ~: else: ::: :::warning [b367: 翻轉世界](https://zerojudge.tw/ShowProblem?problemid=b367) + 假設 a180 為 a 轉 180 度後的陣列,a[i][j] 轉180度後會放在 a180[r-i-1][c-j-1]; + [題意轉180度的意思](https://zerojudge.tw/ShowThread?postid=21462&reply=9472#21462) ::: :::warning [f418: Word Search Puzzle](https://zerojudge.tw/ShowProblem?problemid=f418) + 不會有起始點在下,終點在上面的單字。 + 總共只有3種情況 - r1==r2 橫著印 - c1==c2 直著印 - 其它斜著印,從(r1+1,c1+1),(r1+2,c1+2)......印到(r1+(r2-r1-1),c1+(c2-c1-1)),(r2,c2) + [解題參考](https://www.youtube.com/watch?v=BDHhgndIP-s) ::: :::warning [e787: b2.尋寶地圖(Map)](https://zerojudge.tw/ShowProblem?problemid=e787) + 轉換圖計算行、列和時,重複算的要扣除。 + [題目](https://tpmso.org/toi/wp-content/uploads/question/201912/B2-Map.pdf) + [解題參考(1)](https://tpmso.org/toi/wp-content/uploads/question/201912/B2-Map.pptx)、[(2)](https://www.youtube.com/watch?v=lGYJUGmPzCk) + 兩張地圖資料之間有一個空白行。 ::: ## 五、字串 ### 1. 字串相關操作 + 與 list 操作類似,相加是串接,乘整數是重複。 + 字串與 list 一樣可以 slice,但字串內容不可更改。 ``` python s = 'Hello World' s[1] = 'x' # error a = s[0:5]*2 a = s[:4]+' Python '+s[6:] a = s[::-1] # 反轉字串 ``` + 字串與 list 都可以用 in 檢查元素(字元、子字串)是否在裏面。 ``` python s = 'Hello World' 'H' in s 'E' in s # False 'He' in s 'She' in s # False ``` ### 2. 字串(string)相關函式 + [Python 字串操作(string替換、刪除、擷取、複製、連線、比較、查詢、包含、大小寫轉換、分割等)](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/358746/) + [RUNOOB Python 字符串](http://www.runoob.com/python/python-strings.html) | 字串相關函式 | 意義 | |:----------------|:------ | | str(n) |將變數n轉為字串型態| | len(s) |計算變數s的長度| | str.lower() |將字串中的字母轉成小寫| | str.upper() |將字串中的字母轉成大寫| | str.islower() |判斷字串中的字母是否皆為小寫| | str.isupper() |判斷字串中的字母是否皆為大寫| | str.find('abc') |尋找字串中'abc'的位置| | str.count('abc')|計算字串中'abc'出現的次數| | str.replace(舊子字串,新子字串)|將字串中的舊子字串用新子字串取代| | str.split()|將字串分割成數個子字串(以空白區分)| | str.strip()|去掉字串左右空白| | str.join(sequence)| 指定字符(str)連接串列(sequence)中的元素後,生成新字串 | | 'ab' in 'abcd' | 判斷'ab'是否在'abcd' | | str[::-1] | 將字串反轉 | | [] | 操作同list | :::info EX_5_1:[b428: 凱薩加密](https://zerojudge.tw/ShowProblem?problemid=b428) + ord(): 字元的 ASCII code + chr(): ASCII 轉字元 + if 或 % + Q:可以寫b[1]-a[1]嗎? ::: :::info EX_5_2:[d235: Q10929:You can say 11](https://zerojudge.tw/ShowProblem?problemid=d235) + 11的倍數判別法:奇數位數字和與偶數位數字和相差為11的倍數。 + [1~13的倍數判別法](https://leestar2013.pixnet.net/blog/post/45638266) + 使用列表生成式收進奇、偶項。 ::: :::info EX_5_3:[c015. 10018 - Reverse and Add](https://zerojudge.tw/ShowProblem?problemid=c015) + 輸入的是迴文答案不是 0 次,亦即至少要做一次後才開始判斷。 + [::-1] ::: :::info EX_5_4:[a882: B. 我灰灰的橡皮鴨是個恐怖的危機](https://zerojudge.tw/ShowProblem?problemid=a882) + str.count() ::: :::warning [a009: 解碼器](https://zerojudge.tw/ShowProblem?problemid=a009) + 字串遍歷 ``` python str=input() for a in str: print(a) ``` ::: :::warning [a065: 提款卡密碼](https://zerojudge.tw/ShowProblem?problemid=a065) ::: :::warning [d124: 3的倍数](https://zerojudge.tw/ShowProblem?problemid=d124) + 3的倍數判別法:各個數字和為3的倍數。 + 負號要忽略。 ::: :::warning [b516: 凱撒密碼-商競103](https://zerojudge.tw/ShowProblem?problemid=b516) ::: :::warning [e505: 12602 - Nice Licence Plates](https://zerojudge.tw/ShowProblem?problemid=e505) + 取絕對值函式:abs() ::: :::warning [g006: 密碼備忘錄 (Password)](https://zerojudge.tw/ShowProblem?problemid=g006) + 以陣列儲存字母出現的次數,cnt[ord(ch)-65]+=1。 + 因為最多100個字母,表示次數最大為100,由100->1檢查陣列中是否有這個次數,如果有則輸出 print(chr(i+65), end='') + [解題參考](https://tpmso.org/toi/wp-content/uploads/question/202105/Password.odp) ::: :::warning [c276: 沒有手機的下課時間](https://zerojudge.tw/ShowProblem?problemid=c276) ::: ## 六、函式(遞迴) ### 1. 自定函式宣告語法 ``` python def 函式名稱([參數1, 參數2, ....]): 程式碼 [return 回傳值1, 回傳值2, ....] # 函數可以同時返回多個值(一個tuple) ``` ``` python def 函式名稱([參數1=預設值, 參數2, ....]): 程式碼 [return 回傳值1, 回傳值2, ....] # 函數可以同時返回多個值(一個tuple) ``` ``` python def 函式名稱(*參數): # 參數數量不定,以tuple儲存 程式碼 [return 回傳值1, 回傳值2, ....] ``` :::info EX_6_1:[a623: 3. Combination](https://zerojudge.tw/ShowProblem?problemid=a623) + 將n!寫成函式,在主程式呼叫3次。 + $C(n,k)=\frac{n!}{(n-k)! * k!}$,例如C(4,2)=6。 ::: :::warning [f327: 刪除欄位](https://zerojudge.tw/ShowProblem?problemid=f327)。 + 寫一函式將輸入的字串轉成整數(26進位),A為1,B為2,…,AA為27,AA為28,…。 ``` python for ch in s: n=n*26+ord(ch)-64 ``` ::: :::warning [b112: 5. 高中運動會](https://zerojudge.tw/ShowProblem?problemid=b112)。 + 寫一函式求兩數的最大公因數(輾轉相除法)。 + a=b*q+r → gcd(a,b)=gcd(b,r) ::: ### 2. 遞迴 + 在函式之中呼叫函式自己本身(數學上為函數自己定義自己) + 問題的答案,可從同類的子問題(規模更小)得到。 + 要有終止條件,不然會無窮遞迴下去。 :::info EX_6_2:[95數學學測填充題G](http://cs.cysh.cy.edu.tw/computer_concept_108/高中數學遞迴.pdf) 用黑、白兩種顏色的正方形地磚依照如下的規律拼成若干圖形: ![](https://i.imgur.com/PrDcedl.jpg) 拼第95個圖需用到幾塊白色地磚。(478) ::: ``` python= def f(n): if ~: ~ else: return ~ n=int(input()) print(f(n)) # 5->28 ``` :::info EX_6_3:[a024. 最大公因數(GCD)](https://zerojudge.tw/ShowProblem?problemid=a024) + [原理](https://www.youtube.com/watch?v=fGesPF3QA1U) + a=b*q+r → gcd(a,b)=gcd(b,r) ::: :::warning [e357: 遞迴函數練習](https://zerojudge.tw/ShowProblem?problemid=e357) ::: :::warning [c002: 10696 - f91](https://zerojudge.tw/ShowProblem?problemid=c002) ::: ### 3. 區域變數 vs. 全域變數 - 在函式中的變數為區域變數,在函式外的變數為全域變數。 ``` python= def fun(): a = 10 # 此處的 a 為區域變數 print('函式內',a) a = 5 # 此處的 a 為全域變數 fun() print(a) # a 印出5 ``` ``` python= def fun(): global a # 使用全域變數 a a = 10 print('函式內',a) a = 5 # 此處的 a 為全域變數 fun() print(a) # a 被函式改變,印出 10 ``` ``` python= def fun(): print('函式內',a) # 可以使用全域變數 a,印出 5 a = 5 # 此處的 a 為全域變數 fun() ``` ```python= def fun(a): # 更改參數 a 不會影響函式外的變數 a = 10 print('函式內',a) a = 5 fun(a) print(a) ```