###### 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,...\])
- 字串要加 ' ' 或 " "
- 可用 + 將字串連接
- 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)
+ 字串型態:' ' 或 " " 中的文字
+ 容器型態:
- 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> 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)
```