0%

0-4 條件判斷與基礎邏輯

條件判斷

台大的教學

話不多說,直接上程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<bits/stdc++.h>
using namespace std;

int a,b;

int main(){
cin>>a>>b;
if(a > b){
cout<<a<<" is bigger than "<<b<<'\n';
}
else if(a == b){
cout<<a<<" is equal to "<<b<<'\n';
}
else{
cout<<a<<" is smaller than "<<b<<'\n';
}
}

if

相信不用多加解釋,就是如果…就的意思。

1
2
3
4
if(a > b){
cout<"HI!"<<'\n';
}

這段話的意思是,如果 $a$ 比 $b$ 大,就輸出”HI”。

特別需要注意的有以下幾點:

  1. 條件由小括弧包含住
  2. 滿足條件後要做的事情由大括號包含住
  3. 若滿足條件後要做的事情只有一句(以分號為界),可不包大括弧
  4. if 可單獨存在,也就是說,就算沒有後面的 else if 跟 else ,也是合語法的
  5. if 可多層套疊

第三點的示範如下:

1
2
if(a>b)
cout<<"HELLO!\n";

如果只有一行,可不必以大括弧包含,但還是建議新手盡量都把大括弧寫出來。

第五點的示範如下:

1
2
3
4
5
if(a>b){
if(a>10){
cout<<"HELLO!\n";
}
}

if 裡包另一個 if 是可以的!

請比較下列程式輸出的異同:

1
2
3
4
if(5 < 3){
cout<<"HELLO\n";
cout<<"SECOND_LINE\n";
}
1
2
3
if(5 < 3)
cout<<"HELLO\n";
cout<<"SECOND_LINE\n";

在第一個程式中,不會有任何輸出,但在第二個程式中,卻輸出了:

1
SECOND_LINE

這是因為若 if 不以大括弧包含,其作用範圍僅限一個分號。

順帶一提,C++ 的換行跟空白沒有太多作用,與 python 不同,因此若這樣寫,雖然不會導致編譯錯誤,但其實效果等同於第二個程式,一樣會輸出 SECOND_LINE。

1
2
if(5 < 3)
cout<<"HELLO\n"; cout<<"SECOND_LINE\n";

即使 C++ 沒有像 python 那樣,強制規定你的 tab 跟換行,但為了可讀性與美觀,還是應該在自己的程式碼內適當的使用 tab。一般來說,以大括弧包含起來的程式碼,都應該比括弧外的程式碼多按一個 tab 鍵。

else

不滿足 if 內的情況時,所要執行的指令,以中文來說,就是否則的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<bits/stdc++.h>
using namespace std;

int a,b;

int main(){
cin>>a>>b;
if(a > b){
cout<<a<<" is bigger than "<<b<<'\n';
}
else{
cout<<a<<" is not bigger than "<<b<<'\n';
}
}

上方的 if,條件為 $a > b$,若沒有滿足 $a > b$,則進入下方的 else 區塊,因此若輸入為 5 7,因為 5 並沒有大於 7 (注意,不是小於,是沒有大於) ,因此程式進入 else 區塊,輸出會是:

1
5 is not bigger than 7

也因為這樣,else 無法單獨存在,必定要有 if 在其之前。

else if

有些事情,例如人生,是無法以簡單的二分法作選擇的,這時,我們需要 else if!

雖然我也不覺得用了else if就能為人生作選擇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<bits/stdc++.h>
using namespace std;

int a,b;

int main(){
cin>>a>>b;
if(a > b){
cout<<a<<" is bigger than "<<b<<'\n';
}
else if(a == b){
cout<<a<<" is equal to "<<b<<'\n';
}
else{
cout<<a<<" is smaller than "<<b<<'\n';
}
}

以中文翻譯,else if大概就是”否則,如果”的意思吧!

當輸入為 5 7 時,程式首先判斷第一個條件:

1
如果 a > b ......

此時,$a$ 是 5,$b$ 是 7,5 並沒有大於 7,因此落入下一個區塊。

第二個區塊為:

1
2
3
else if(a == b){
cout<<a<<" is equal to "<<b<<'\n';
}

5 並沒有等於 7,因此進入最後區塊,輸出:

1
5 is smaller than 7

聰明的你應該可以發現,else if 是可以無限串接的!也就是說,可以這樣寫。

1
2
3
4
5
6
7
8
9
10
11
12
if(a){
...
}
else if(b){
...
}
else if(c){
...
}
else if(d){
...
}

沒加 else if 的後果

讓我們試試將上方程式碼中的 else if 改成 if。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<bits/stdc++.h>
using namespace std;

int a,b;

int main(){
cin>>a>>b;
if(a > b){
cout<<a<<" is bigger than "<<b<<'\n';
}
if(a == b){
cout<<a<<" is equal to "<<b<<'\n';
}
else{
cout<<a<<" is smaller than "<<b<<'\n';
}
}

接著執行程式,輸入同樣的 5 7,結果為:

1
5 is smaller than 7

恩,一模一樣,所以沒有差…嗎?

輸入 7 5,結果為:

1
2
7 is bigger than 5
7 is smaller than 5

為什麼?

因為,上方的兩個if,是分開的!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<bits/stdc++.h>
using namespace std;

int a,b;

int main(){
cin>>a>>b;
if(a > b){
cout<<a<<" is bigger than "<<b<<'\n';
}



if(a == b){
cout<<a<<" is equal to "<<b<<'\n';
}
else{
cout<<a<<" is smaller than "<<b<<'\n';
}
}

第二段中,那個 if/else 片段的意思是:

如果 a 等於 b,輸出 a is equal to b,否則,輸出 a is smaller than b

因此,程式判斷了 a 不等於 b,所以產生了第二個輸出!

基礎邏輯

  1. > 大於
  2. < 小於
  3. == 等於 (注意,不是=)
  4. != 不等於
  5. >= 大於等於
  6. <= 小於等於
  7. && 且
  8. || 或
  9. ! 否

運用這十種組合,搭配上方的 if else,我們終於可以寫出一點自己的東西了!

&&(and) 與 ||(or)

&&(且) 與 ||(或) 在判斷式中的使用法,是連接很多個不同的敘述。例如:

1
2
3
if( a>=5 && a<b ){
...
}

意思即為:若 $a \ge 5$ 以及 $a<b$ 成立的話,就…

1
2
3
if( a>=5 || a<b || a>c){
...
}

這句的意思則是,若 $a \ge 5$ 或 $a<b$ 或 $a>c$ 任何一個成立的話,就…

!(not)

!的運用則是,加在一判斷式之前,若判斷式成立則結果為非,若不成立則為是。

簡單來說,把判斷的結果相反就對了

1
2
3
if(!(a>5)){
...
}

這句的意思是,如果 $a>5$ 不成立的話,就…

在這個範例裡,這其實等同於:

1
2
3
if(a<=5){
...
}

後者明顯好懂許多,因此,好懂也是程式中重要的一環!

來點範例吧!

我們知道一個西元年份是閏年的話,它必須是4的倍數,但如果是 100 的倍數就不閏,但如果它是400的倍數就又是閏年,真麻煩

因此,要判斷一個西元年分是不是閏年,可以這麼寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int year;
cin>>year;
if(year%4==0){
if(year%100==0){
if(year%400==0){
cout<<"YES\n";
}
else{
cout<<"NO\n";
}
}
else{
cout<<"YES\n";
}
}
else{
cout<<"NO\n";
}

另一種寫法是

1
2
3
4
5
6
7
8
9
10
11
12
if(year%400==0){
cout<<"YES\n";
}
else if(year%100==0){
cout<<"NO\n";
}
else if(year%4==0){
cout<<"YES\n";
}
else{
cout<<"NO\n";
}

對於同樣的一個問題,我們可能會產生不同解法,而這就是程式解題的迷人之處!

特別注意

小於/大於不支援超過兩個數字的比較,因此請勿寫成:

1
if(a<=b<=c)

危險的地方是,這個程式碼並不會導致編譯錯誤
進行運算時,程式首先判斷 a<=b,得到的結果為 true / false。接著,再將其與 c 做比較,因此如 a <= b,會變成:

1
if(true <= c)

而 true 的值為 1,false 為 0。因此程式便判斷 1 <= c 是否成立,至此,已經完全不是原來所想的那樣了。

若要判斷 $a \le b \le c$,應該寫成這樣才是正確的:

1
if(a<=b && b<=c)

練習

條件判斷這個章節,可能是你第一個卡關的地方,有些人需要大量的實際練習才能熟悉,因此這裡提供大量題目,讀者可根據自己狀況進行練習。

TOJ 94

TOJ 95

TOJ 96

TOJ 102

TOJ 103

TOJ 535

TOJ 538

★★ TOJ 461

★★★★★ ZJ f312

AC Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// TOJ 94
#include<iostream>
using namespace std;
int main(){
int a ;
cin >> a ;
if(a >= 3 && a <= 5){
cout << "Spring!" << endl ;
}
else if (a >= 6 && a <= 8){
cout << "Summer!" << endl ;
}
else if (a >= 9 && a <= 11){
cout << "Autumn!" << endl ;
}
else{
cout << "Winter!" << endl ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// TOJ 95
#include <bits/stdc++.h>
using namespace std;

int main(){
int a,b;
cin>>a>>b;
if(a==1){
if(b>=8) cout<<"PASS!\n";
else cout<<"FAIL! You see see you!\n";
}
else if(a==2){
if(b>=9) cout<<"PASS!\n";
else cout<<"FAIL! You see see you!\n";
}
else{
if(b==10) cout<<"PASS!\n";
else cout<<"FAIL! You see see you!\n";
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// TOJ 96
#include<iostream>
using namespace std;

int main(){
int a,c,ans;
char b;
cin >> a >> b >>c;
if(b=='+'){
cout <<a<<" + "<<c<<" = "<<(a+c)<<endl;
}
else if(b=='-'){
cout <<a<<" - "<<c<<" = "<<(a-c)<<endl;
}
else if(b=='*'){
cout <<a<<" * "<<c<<" = "<<(a*c)<<endl;
}
else{
if(c==0){
cout <<"ERROR"<<endl;
}
else{
cout <<a<<" / "<<c<<" = "<<(a/c)<<" ... "<<(a%c)<<endl;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// TOJ 102
#include<iostream>
#include<iomanip>
using namespace std;

int main() {
double a,b;
char k;
cin >> a >> k >> b;
cout << fixed << setprecision(4);
if(k == '+'){
cout << a << ' ' << k;
cout << ' ' << b << " = ";
cout << a+b << endl;
}
else if(k == '-'){
cout << a << ' ' << k;
cout << ' ' << b << " = ";
cout << a-b << endl;
}
else if(k == '*'){
cout << a << ' ' << k;
cout << ' ' << b << " = ";
cout << a*b << endl;
}
else if(k == '/'){
if(b == 0){
cout << "ERROR\n";
return 0;
// return 0 表示結束整個程式的意思
}
cout << a << ' ' << k;
cout << ' ' << b << " = ";
cout << a/b << endl;}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// TOJ 103
#include <bits/stdc++.h>
using namespace std;

int main() {
string a,b,c,d;
cin>>c>>a;
cin>>d>>b;
if(a==b&&c==d)
cout<<"GOOD"<<"\n";
else if(a==b||c==d)
cout<<"=~="<<"\n";
else
cout<<"OTZ"<<"\n";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// TOJ 535
#include <bits/stdc++.h>
using namespace std;
int main(){
int s;
cin >> s ;
if(s == 100) cout << "S\n";
else if(s>=90) cout << "A\n";
else if(s>=80) cout << "B\n";
else if(s>=70) cout << "C\n";
else if(s>=60) cout << "D\n";
else cout << "F\n";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// TOJ 538
#include <iostream>
using namespace std;

int main(){
double math, eng, sci, data, pro, score, tagert;
cin >> eng >> math >> sci >> data >> pro >> tagert;

score = (((eng * 1.25) + (math * 2) + sci) / 63.75) * 20 + 0.4 * (pro + data);

if (score >= tagert){
cout << "YA\n";
}
else{
cout << "QQ\n";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// TOJ 461
#include<iostream>
using namespace std;
int main(){
double x;
cin>>x;
if(x==0||x==180){
cout<<"2"<<'\n';
}
else{
cout<<"4"<<'\n';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// ZJ f312
#include<bits/stdc++.h>
using namespace std;

int a1,b1,c1,a2,b2,c2,n;

int main(){
cin>>a1>>b1>>c1>>a2>>b2>>c2>>n;

double x = 1.0 * (2 * a2 * n + b2 - b1) / (2 * (a1 + a2));
// 找到二次函數極值發生的位置,與端點取max
int ans = -100000000;

int p = x, l = n-p;
if(0 <= p && p <= n){
int ans1 = a1 * p * p + b1 * p + c1 + a2 * l * l + b2 * l + c2;
if(ans1 > ans) ans = ans1; // ans = max(ans, ans1)
}

// 微分後答案不一定是整數,因此要試兩個點
p++, l--;
if(0 <= p && p <= n){
int ans1 = a1 * p * p + b1 * p + c1 + a2 * l * l + b2 * l + c2;
if(ans1 > ans) ans = ans1;
}

int ans0 = a2 * n * n + b2 * n + c2 + c1; // 左端點
int ansn = a1 * n * n + b1 * n + c1 + c2; // 右端點
if(ans0 > ans) ans = ans0; // ans = max(ans, ans0)
if(ansn > ans) ans = ansn; // ans = max(ans, ansn)
cout<<ans<<'\n';
}