2023/11/08
主講:YuDong
https://docs.google.com/spreadsheets/d/1_CVuBW38GNuu_-hs7-Q_ZMQHQrnDq1mKs08dqumvVzA/edit?usp=sharing
講義內所寫的程式碼都是用來舉例說明用
如果你是要解題目,請不要直接複製程式碼送出答案。
因為你只會吃到一堆 WA
然後沒有學到任何東西😭
今天這堂可能對初學者來說有點難度
可能沒辦法當下在課堂吸收
但沒有關係,大家都有這份講義、有題單、有題解
也有開放給大家問問題的 Discord 社群
不會的地方、不懂的觀念
一定要發問
資研社可以讓你問到懂
如果某個人的說法你聽不太懂
也可以再問問其他人
多聽取不同的想法
也是進步的方式之一
https://app.sli.do/event/qmsxe97ZUwPmwQhgJu6K1i
詳細除錯方法請至第二次社課講義的這頁
程式沒寫錯 但沒縮排沒空格閱讀起來較困難
適時的空格與縮排有助於閱讀與除錯
這節課會教如何保留小數點
請至第二次社課講義
變數
條件判斷式
延伸知識
在上一次社課中,我們簡單介紹了變數的基礎
以及介紹兩個變數型別:Integer (整數) 和 String (字串)
而現在我們要來介紹更多變數的型別!
除了 int 與 string 以外,還有一些型別是我們常常用到的
這邊用一個表格整理給大家看
名稱 | 寫法 | 備註 |
---|---|---|
整數 | int | 範圍 \(-2^{31}\) ~ \(2^{31}-1\) |
大一點的整數 | long long | 範圍 \(-2^{63} \sim 2^{63} - 1\) |
浮點數 | double | 儲存非整數的時候使用 |
字元 | char | 以 ' 包住字元 |
字串 | string | 以 " 包住字串 |
布林值 | bool | 僅有兩個值:true / false |
括號內為我們要將其轉變的型別
double 就是浮點數(小數點)的意思
通常是取到小數點後第五位
這題輸出是 1.75
APCS 常考觀念
問:會輸出什麼?
答:10
藍色 的區域是全域變數影響的範圍
綠色 的區域是區域變數影響的範圍
而在 main 函式當中,會先存取該函式內的變數的值。
在我們要表達一個條件、情況的真假時,就會用到布林值
等等要教的 條件判斷式 亦是如此
一般來說,會用在我們要確認某個性質是否成立的時候
例如:檢查熱水器有沒有關
就只會有兩種情況:有關/沒關
而布林值的值剛好只有兩種:true 真/false 假
布林值的重要性質:
輸出:
宣告一個布林變數來儲存布林值。
if (1 < 2) {
cout << "Yes, this is real.";
}
這段程式碼是一個簡單的條件判斷式
而 1 < 2 這邊這個判斷結果是 【真】
在這裡,判斷結果的布林值就是: true
既然我們學會了 int 和 string 變數 的運用
剛剛也有複習ㄌ
那麼如果我們需要讓程式在某些情況下
執行我們要所要的結果
就會需要進行 判斷
先來認識一下 基礎運算子 與 邏輯運算子吧!
在【條件判斷式】中
這些運算子是相當重要的
要判斷,就要先有比較。
要比較,就要先有邏輯。
定義 | 運算子 | 解釋 |
---|---|---|
相等 | == | a 與 b 相等 50 == 50 |
不相等 | != | a != b 就像 50 != 100 |
大於 | > | a > b 就像 100 > 50 |
小於 | < | a < b 就像 50 < 100 |
大於等於 | >= | a >= b 就像 100 >= 50 |
小於等於 | <= | a <= b 就像 50 >= 100 |
要注意的是: 等於是 == 而不是 =
在程式語言中, = 是用於賦值給變數的
== 才是「判斷是否相等」的意思
或(OR): ||
且(AND): &&
相反(NOT): !
SA 講義有超級詳細的介紹
各位可以先記錄下來,或者等等回來翻閱這裡
下面來介紹一下 邏輯優先度
課外文章:運算子的優先權
接下來,要開始正式進入到 【條件判斷式】 了
顧名思義,就是【如果】
舉例:
#include <bits/stdc++.h>
using namespace std;
int main() {
int a,b;
cin >> a >> b;
if(a > b) {
cout << a << "is bigger than " << b << "\n";
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main() {
int a,b;
cin >> a >> b;
if(a > b) cout << a << "is bigger than" << b << "\n";
return 0;
}
如果 期末成績 \(a\) \(<\) \(40\) 那麼 你要去重補修
#include <bits/stdc++.h>
using namespace std;
int main() {
int a = 39; // 這是你的期末分數
if (a < 40) { // 如果 期末成績 a < 40 那麼 就要去重補修了。
cout << "You must retake the course. HAHA";
}
return 0;
}
執行結果
You must retake the course. HAHA
例子:
如果 期末成績 \(a < 40\) 哈哈重修
否則 \(a >= 60\) 代表通過
可以看到 有兩種條件
那麼我們該怎麼去做判斷呢?
else 也就是【否則】
#include <bits/stdc++.h>
using namespace std;
int main() {
int a,b;
cin >> a >> b;
if(a > b) {
cout << a << "is bigger than" << b << "\n";
} else {
cout << a << "is smaller than" << b << "\n";
}
return 0;
}
舉個例子:
如果 期末成績 \(a < 40\) 重修
否則 \(a >= 60\) 通過 來看
期末成績 \(a < 40\) 是 第一個條件
而 \(a >= 60\) 則是剩下的條件
如果所有的 if 都不成立,那麼 else 的部份將被執行。
我們來看看 else 怎麼實作的吧
#include <bits/stdc++.h>
using namespace std;
int main() {
int a = 39; // 這是你的期末分數 重修的那種。
if (a >= 60) { // 如果 期末成績 a >= 60 那麼你通過了。
cout << "You passed.";
} else { // 期末成績 a 沒有 >= 60 那麼你要重修了 哈哈。
cout << "You must retake the course. HAHAHAHAHA.";
}
return 0;
}
而在上面的程式碼中 ,我們的分數為 \(39\) 分
明顯 \(a\) 是 \(< 40\) 的
else 則是處理了 \(a >= 60\) 以外的情況
這意味著,我們終究逃不過重修的命運 x)
很多情況是沒有辦法直接二分法解決的
這時候,就要用到我們的 else if 了
用法與 else 大致相同
舉個例子吧:
如果 期末成績 \(a >= 60\) 表示通過
而 \(40 <= a\) 且 \(a < 60\) 則是補考人
否則 \(a < 40\) 重修
如果 期末成績 \(a >= 60\) 通過
\(40 <= a\) 且 \(a < 60\) 是補考人
而當 \(a < 40\) 重修
#include <bits/stdc++.h>
using namespace std;
int main() {
int a = 53; // 這是你的期末分數
if (a >= 60) { // 如果 期末成績 a >= 60 那麼你通過了。
cout << "You passed.";
} else if (a >= 40) { // 期末成績 40 <= a < 60 的情況
cout << "You must attend the make-up exam. RIP.";
} else { // 期末成績 a 沒有 > 40 那麼你要重修了 哈哈。
cout << "You must retake the course. HAHAHAHAHA.";
}
return 0;
}
舉例:
期末成績 \(a > 75\) 且 \(a <= 100\) 是 電神
輸出 Orz
這種情況 該怎麼寫呢?
#include <bits/stdc++.h>
using namespace std;
int main() {
int a = 88; // 這是期末分數 八成是別人的 x)
if (a > 75) { //如果 a > 75
if (a <= 100) { //如果 a <= 100
cout << "Orz";
}
}
return 0;
}
這樣寫是正確的
但是 能不能再簡化一點呢?
太多的 if 包在一起
會影響日後 debug 的難度與可讀性。
還記得我們剛剛提到的
或(OR): ||
且(AND): &&
相反(NOT): !
幫各位搬運過來了
還記得我們剛剛提到的 邏輯運算子 嗎
利用邏輯運算子,可以讓程式碼更簡潔、好讀、易於維護
#include <bits/stdc++.h>
using namespace std;
int main() {
int a = 88; // 這是期末分數 八成是別人的 x)
if (a > 75 && a <= 100) { //如果 a > 75 而且 a <= 100
cout << "Orz";
}
return 0;
}
這樣 我們就不需要再包一個 if 在第一個 if 裡面了
先來複習一下怎麼寫題目 xD
也可以在 slido 上面發問!
哪邊聽不懂的也可以再重講一次歐
助教們都會去幫忙喔
必做題:
ZJ d064 -ㄑㄧˊ 數?
ZJ d058 - BASIC 的 SGN 函數
–
計時器
ZJ d068 - 該減肥了!
ZJ a003 兩光法師占卜術
ZJ d073 - 分組報告
ZJ d050 妳那裡現在幾點了?
ZJ d060 - 還要等多久啊?
ZJ d066 - 上學去吧!
ZJ d460 - 山六九之旅
ZJ b877 - 我是電視迷
(等完成上面的題目再挑戰看看!)
題目整體的意思就是:判斷 \(n\) 是不是奇數
如果是奇數輸出 Odd,否則輸出 Even
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; cin >> n;
if(n % 2 == 0) {
cout << "Even\n";
} else {
cout << "Odd\n";
}
return 0;
}
題目把它描述的看起來很難
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; cin >> n;
if(n > 0) cout << 1 << "\n"; //如果 n > 0
else if(n == 0) cout << 0 << "\n"; //如果 n = 0
else cout << -1 << "\n"; //如果 n < 0
return 0;
}
剛剛提到,int 儲存的數字範圍是 \(-2^{31} \sim 2^{31}-1\)
精確來說是 \(-2147483648 \sim 2147483647\)
這串數字不必背起來 只需要知道大概是 \(2 \times 10^{10}\) 就好
若數字比能儲存的範圍還大 就會發生溢位
產生 非預期的結果
更多詳細知識可閱讀 變數上限與溢位 by SA
為了避免掉有些題目給的數字較大
使用 int 會有溢位問題,通常會用:
但要注意做了這件事之後
整份程式碼的 int 就都會是 long long 的狀態了
使用後要記得順便將 main 函式回傳的 int 改成 signed
除了競程用途以外,強烈建議不要使用於開發
無號整數與有號整數
INT_MAX = 2147483647
INT_MIN = -2147483648
更多的巨集表達式在這篇文章
有興趣的可以看一下
min(a,b):對 \(a\ b\) 取最小值
max(a,b):對 \(a\ b\) 取最大值
兩個函式都具有交換律
所以可以這樣用:
延伸題:ZJ d065. 三人行必有我師
輸出結果
3.14159
轉換公式:\((f-32) \times 5/9\)
剛剛提到的 比較運算子 == 為相等之意
但是浮點數的比較因為誤差的關係
不能使用 == 進行比較
更多的資訊在這邊文章:浮點數的誤差
定義:用到幾個東西
#include <bits/stdc++.h>
using namespace std;
int main() {
int age; cin >> age;
cout << (age > 18 ? "is Adult" : "is a Kiddo") << "\n";
return 0;
}
如果不用三元運算:
#include <iostream>
using namespace std;
int main() {
int age; cin >> age;
if(age > 18) {
cout << "is Adult\n";
} else {
cout << "is a Kiddo\n";
}
return 0;
}
程式碼又臭又長💀
用了三元運算後…
#include <bits/stdc++.h>
using namespace std;
int main() {
int age; cin >> age;
cout << (age > 18 ? "is Adult" : "is a Kiddo") << "\n";
return 0;
}
程式碼變得更簡潔了 讚啦
對,就是這個 switch
今天來介紹一下 怎麼在馬力歐賽車裡面打網球
switch 語法
在競程中比較常用到 if
switch 則相對少見
但以下幾個時機,是適合使用 switch 的
switch (運算式或變數名稱) {
case 符合數字或字元:
符合此 case 執行的東西;
break;
case 符合數字或字元:
符合此 case 執行的東西;
break;
default:
符合此 case 執行的東西;
break;
}
請記得在每個 case 中 break
給定一 \(N\),表示這次段考的分數(\(0 \le N \le 100\))
學校為了統計方便
會將分數統一都會除以 \(10\)
如果分數等於 \(9\) 或 \(10\),其對應等第為 A
如果分數等於 \(8\),其對應等第為 B
如果分數等於 \(7\),其對應等第為 C
如果分數等於 \(6\),其對應等第為 D
其餘的情況,都等第都為 E
礙於時間因素,這邊給大家兩個連結
感謝各位認真參與第三次社課
一如既往,需要各位提供意見給我們
令我們知道各位在課程當中的想法
請到 Discord 社團公告填寫或用手機掃描以下 QR Code