南大附中資訊研究社 NFIRC 1st

第 2 次社課講義

2023/10/25
主講:ShiYu


課前準備

  • 社費
  • 幹部初選
  • 頒獎
  • 訂飲料
  • 點名
  • 註冊帳號

交社費

課程結束 填完回饋表單之後
可以找總務交社費 300$
我們會給你收據
今天沒帶的可以下次上課 11/8 再交


幹部初選


目前社團幹部

  • 社長 ( \(1\ 位\) ):黃士育
  • 副社長兼網管 ( \(1\ 位\) ):吳覲宇
  • 公關 ( \(2\ 位\) ):張英祈、
  • 總務 ( \(1\ 位\) ):許晉菕
  • 文書 ( \(3\ 位\) ):吳瑀衡、、
  • 助教-TA ( \(5\ 位\) ):
    • 張昱德

現任幹部初選名單

等等會發意願單傳下去
有在名單上的人可以勾選要不要擔任

  • 公關:方○媛
  • 文書:王○勝、蔡○孟
  • 庶務:邱○軒、鄭○諺、張○圩

現任幹部初選名單

  • 助教(有程式基礎)
    • 郭○澤
    • 李○靜
    • 莊○任
    • 陳○興
    • 吳○毅

實習幹部初選名單

  • 翁○恩
  • 曹○智
  • 郭○賢
  • 徐○蕾
  • 潘○妘
  • 薛○璇
  • 劉○勳
  • 翁○佑
  • 謝○彤
  • 陳○康
  • 余○傑
  • 蔡○安

頒獎🍼🧃🍷🍺🍸🥤

資訊研究社社團介紹與入門基礎演算法競賽知識之超級眼力測試暨超極限競技搶答大賽

校內賽全校決賽決選 前三名 恭喜!


請正宗老師、現任幹部及前三名得獎者
等等點名時間來找總務訂飲料
社課結束後會給大家帶回教室喝


註冊帳號

本次社課需使用以下網站

請各位用自己常用的 Gmail 註冊帳號
已註冊的人可以幫幫你旁邊的人😭


Replit

社團課中寫程式使用的軟體
可用網頁瀏覽與編輯
也可以即時存檔在雲端
回去也可以開來看今天寫的程式


Step1:

使用你常用的 Gmail 創建一個 Replit 帳號
點擊這顆按鈕 ↓


Step2:創建一個檔案


Step3:選好 C++ 打好今天日期 創建


Zero Judge

高中生程式解題系統

有大量題庫 適合程式新手
社團使用網站中的課程功能
讓大家加入課程
查看我們每次社團課整理的題單


Step1

使用自己常用的 Gmail 帳號即可
學校太爛直接把學生的帳號註冊鎖起來了😡


Step1-2

註冊的時候記得選學校:
臺南州立臺南農業學校

國立臺南大學附屬高級中學


Step2

登入畫面:

✅我是機器人


Step3

鼠標停在個人名字上方
按下 參加課程


Step4

輸入課程代碼:

xyamzm

看不到的大叫一聲,我去幫你


點名時間!

在喊在
趁現在註冊 Replit、Zero Judge
ZJ 課程代碼

xyamzm


快速複習上次社課內容

  • 社團課表
  • 社團教學方式
  • Discord 社群
  • 各種競賽、社群、OJ、營隊
  • 競程術語
  • 課程資源彙整

課表


上學期

C++ 基礎語法

節次 課程內容
\(1\) 社團整體介紹|了解社團運作|小遊戲
\(2\) 註冊帳號|基本架構|輸入輸出|變數使用|算術運算子|程式題實作
\(3\) 條件判斷式|邏輯、比較運算子|變數型態
\(4\) 迴圈|陣列|字串
\(5\) 巢狀迴圈|二維陣列
\(6\) 期末練習賽|社團聚餐🍕|題目講解

下學期

基礎資料結構與入門演算法

節次 課程內容
\(7\) 複雜度分析(空間&時間)|暴力法與窮舉法
\(8\) 基礎資料結構(向量|堆疊|佇列)
\(9\) 函式|遞迴
\(10\) 排序法(氣泡|選擇|插入|快速)
\(11\) 二分搜尋法
\(12\) 期末練習賽|社團聚餐🍕|題目講解

會根據社員的學習狀況調整或刪減課程內容


教學方式

  • 良好的學習環境
  • 助教協助教學
  • 題單幫助進步
  • 獎勵制度
  • 即時匿名提問
  • 延伸知識與課外補充

本節課的匿名提問 Slido

https://app.sli.do/event/9FcZVd2Srnvh9o2QzWWtae


程式競賽

  • APCS 大學程式設計先修檢測
  • YTP 少年圖靈計畫
  • 資訊學科能力競賽
  • NPSC 網際網路程式設計全國大賽
  • TOI 初選
  • IOI 國際資訊奧林匹亞
  • FB Hacker Cup
  • 金盾獎

Discord 社群推薦


各大 OJ


各大營隊

  • NHDK / SCIST 舉辦的營隊
  • IONCamp
  • APCS Camp
  • IOI Camp
  • AIS3 資安營
  • 台灣好厲駭

競程術語

  • 電:超帥超強超厲害的意思
  • 電神: 超帥超強超厲害的人
  • orz:跪倒在地、對電神膜拜 🛐
  • 椒麻:教嗎?
  • 裝弱:假裝自己很弱 可簡寫成:裝
  • 破台:解完此次比賽的所有題目
  • 水題:很簡單的題目
  • 燒雞:比賽發揮不佳、失常,引申為 搞砸了 的意思

競程術語:OJ 篇

  • AC (Accepted):通過檢測
  • WA (Wrong Answer):沒有通過檢測
  • TLE (Time Limited Exceed):程式碼執行過久
  • RE (Runtime Error):程式碼停止運行
  • CE (Compile Error):程式碼無法編譯
  • MLE (Memory Limited Exceed):程式碼使用太多記憶體

課程資源彙整頁面

每節社課上完都會更新
有社課講義 學習資源 題單
以及其他各種上課提到的連結
請社員們多多運用


大家請記得看社團公告

每次社課的前一天晚上
我們都會在 Discord 的
發布社課通知提醒大家社課的注意事項
有些要帶的東西或要做的事情
其他頻道可以自己選擇要不要看
但社團公告的頻道一定要看


第一次社課的課後檢討會議

每節社課結束後的晚上我們幹部
都會開課後檢討會議
希望透過每次社課的回饋表單與課後檢討會議
能了解社員的想法、建議以及上課感受
讓我們能夠即時的調整並改進
提供良好的課程內容給大家


第二次社課目錄

  • 註冊帳號 加入課程
  • 撰寫你的第一個 C++ 程式
  • 獲得人生中第一個 AC
  • 輸入輸出與變數的結合
  • 四則運算
  • 競程重要技巧
  • 開啟你的 AC 之路
  • 程式規範與除錯
  • 延伸知識
  • 課程回饋

本次社課流程

  1. 註冊帳號 加入課程
  2. 講解 C++ 基本架構、如何輸出
  3. 給大家練習撰寫並成功解題
  4. 講解如何使用變數、輸入
  5. 如何用程式實做四則運算
  6. 解題與除錯
  7. 講解延伸知識

此篇講義內容分類

  1. 必學語法
  2. 延伸知識
  3. 課外知識

有相關的資料都會附上文章連結
給大家回家自己打開來看
有興趣的人可以花點時間研究


必學語法:課程大部分時間都會教必學語法 有基礎的人可能會覺得無聊
延伸知識:課堂的最後講解延伸知識 能聽懂算很厲害
課外知識:在延伸知識中又有更難一點的知識給已經有基礎的人了解
其他人聽不懂也沒關係 不會影響很大


撰寫你的第一個 C++ 程式

  • C++ 基本架構
  • 簡單了解每行的意義
  • 撰寫基本架構
  • 輸出 cout <<
  • 完成!

C++ 基本架構

一個程式的骨架
之後 每一份程式
都從它開始

#include <iostream> using namespace std; int main() { return 0; }

讓我們來簡單了解每行的意義

#include <iostream> // 導入標頭檔,裡面包含輸出功能(cout) using namespace std; // 使用標準命名空間,簡化接下來的程式碼 int main() { // 主程式,在程式中會先被執行 // 這裡放你寫的程式碼 return 0; // 回傳 0 代表程式結束 }

在程式碼中 // 代表註解的意思
// 後的文字(同一行)不會被電腦執行
所以很適合用來跟別人解釋這一行在幹嘛
如果要解釋很多行 可以用 /* */ 把註解包起來

詳細介紹基本架構請至 延伸知識


五分鐘時間讓各位寫好基本架構

#include <iostream> using namespace std; int main() { return 0; }
  • 第一次 可以用抄的 但要抄對
  • 第二次 試著邊抄邊理解每行用意
  • 第三次 理解完後自己寫 忘記可以偷看
  • 第四次 可以不用看就很順暢的寫出來
  • 第 n 次 拿紙筆讓你默寫也寫得出來

但我們不會像某選修老師一樣真的叫你手寫程式碼


輸出 output

程式中可以用 iostream 中的 cout (吸奧)函式
在終端機輸出你想說的話


程式碼

#include <iostream> using namespace std; int main() { cout << "Welcome to\nNFIRC 1st."; return 0; }

執行結果

Welcome to 
NFIRC 1st.

#include <iostream> using namespace std; int main() { cout << "Welcome to\nNFIRC 1st."; return 0; }

在第 5 行中
運用 cout 輸出 Welcome to NFIRC 1st. 字串

  • 在 cout 跟要輸出的東西中間用 << 串接
  • 輸出文字 都要記得加上 " "
    把字串包起來
  • \n 來換下一行 換幾行就用幾個 \n\n\n\n

觀念補充

有些人學過 C++ 會用 endl (end line) 來換行
但在競程中 通常都用 \n 來換行

原因請至 延伸知識


輸出串接多個東西

只要用 << 就可以串接多個東西

#include <iostream> using namespace std; int main(){ cout << "Welcome to\nNFIRC " << 1 << "st.\n"; return 0; }

執行結果

Welcome to
NFIRC 1st.

注意

輸出盡量用英文 避免使用中文
原因是會產生預料之外的問題
例如亂碼或許功蓋問題

許功蓋問題請至 延伸知識


獲得人生中第一個 AC

學會了 C++ 基本架構和 cout 輸出後
請所有人到 ZeroJudge 課程中的
NFIRC 第一節社課必做題與練習題
完成 1 d483. hello, world
體驗 AC 的感覺


電腦基本常識

Ctrl + C 複製
Ctrl + V 貼上

寫完程式碼要上傳(submit) OJ 時
使用競程小技巧可以更快速複製程式碼

競程小技巧

Ctrl + A 全選
Ctrl + C 複製

「 Ctrl + AC,每題都 AC 」


AC Code 解答

#include <iostream> using namespace std; int main(){ cout << "hello, world\n"; return 0; }


輸入 cin >>

當你想在終端機輸入東西給電腦時
可以用 cin (吸硬) 函式
輸入就是輸出的
相反
cout <<
cin >>
在學輸入之前 我們要先來學如何使用變數 變數


變數 variable

一個可以裝特定東西的 容器
儲存任何程式需要 記住 的東西


變數的四大屬性

今天只簡單介紹 整數字串 型別
第三次社課會詳細介紹型別種類、用途與範圍

  • 型別 type:代表它適合裝什麼
  • 名稱 name :用來區別不同的變數
  • 值 value:變數裡頭裝的東西,會是一個符合變數型別的數值
  • 值 address :該變數被放在哪裡
    (之後如果有機會才會教到 先不用理它)

宣告

使用變數之前一定要先宣告
宣告方法:型別 變數名稱

int number;
string name;

賦值 assign

給變數存入值的行為
我們稱為 賦值=賦值運算子

int number = 12;
string name = "ShiYu";

並不是 number 與 12 相等的意思
而是把 12 指派給 number 這個變數
宣告時同時賦值的行為
我們稱為 初始化


int number = 12; string name = "ShiYu";
  • 第 1 行中

    • 型別:整數 int ( integer 的縮寫)
    • 名稱:number
    • 值:12
  • 第 2 行中

    • 型別:字串 string
    • 名稱:name
    • 值:"ShiYu"

學完如何宣告變數後

讓我們回到 如何輸入

步驟:

  1. 宣告變數
  2. 輸入

1. 宣告變數

string name;

因為我們要輸入我們的名字進去這個變數中
所以宣告時可以先不用賦值給這個變數
但要記得 變數還沒賦值時 不能讀取這個變數的值
因為未初始化的變數 值是未定義的
這時候讀取會產生 未定義行為(Undefined behavior)
有興趣的人可以課後點 此篇連結 研究


2. 輸入

宣告變數後就可以使用 cin >> 把輸入的值存入變數

string name; cin >> name;

cin 也可以用 >> 串接來一次輸入多個變數

string name1,name2; int age; cin >> name1 >> name2 >> age;

在第 1 行中也同時宣告多個 字串型別的變數

注意:

同型別才能同時宣告 不同型別請分開宣告


結合

學完了基本架構、變數、輸入、輸出
現在把它結合起來組成完整的程式


結合基本架構、變數、輸入輸出的程式碼

#include <iostream> using namespace std; int main() { string name1,name2; int age; cin >> name1 >> name2 >> age; cout << "name1 = " << name1 << "\nname2 = " << name2 << "\n\nage = " << age << "\n"; return 0; }

第 8 行 cout 部分為了避免太長 換行對齊較易讀


程式碼執行結果

輸入 input

ShiYu Yudong 16

輸出 output

name1 = ShiYu
name2 = Yudong

age = 16

競程重要技巧

使用 <bits/stdc++.h> 萬用標頭檔

此標頭檔裡導入了以下常用的標頭檔

#include <iostream> #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector>

裡面包含一開始基本架構中寫的 iostream 標頭檔
和其他常用資料結構函式庫
意味著我們不用每次要使用什麼函式
都去查那個函式的標頭檔
只要導入 萬用標頭檔 就夠了
下次實作時第一行可以用
#include <bits/stdc++.h>
請背起來 不然去考 APCS 會花很多時間打標頭檔


開啟你的 AC 之路

請所有人到 ZeroJudge
完成 2 a001. 哈囉
再獲得一個 AC 吧!


AC Code

#include <bits/stdc++.h> using namespace std; int main() { string s; cin >> s; cout << "hello, " << s << "\n"; return 0; }

等等 出錯了?

如何除錯、程式規範與撰寫習慣


常見錯誤

  • 忘記加分號 ;
  • 字拼錯
  • 忘記宣告變數
  • cin cout 串接方向記相反
  • 括號用錯或沒加或加錯地方

忘記加分號 ;

#include <bits/stdc++.h> using namespace std int main() { string s cin >> s cout << "hello, " << s << "\n" return 0 }

字拼錯

incloud include
namesapce namespace
mian main
hollow hello
count cout
retrun return

忘記宣告變數

#include <bits/stdc++.h> using namespace std; int main() { // 這裡沒宣告 s ,電腦不知道下一行的 s 是什麼 cin >> s; cout << "hello, " << s << "\n"; return 0; }

cin cout 串接方向記相反

cin << cin >>
cout >> cout <<

串接方向相反會導致
CE (Compile Error) 編譯錯誤


  • 括號用錯或沒加或加錯地方
#include (bits/stdc++.h) using namespace std; int main < string s; cin >> s; cout << "hello, " << s << "\n"; return 0; >
#include (bits/stdc++.h) #include <bits/stdc++.h>
int main int main( )

養成良好的程式撰寫習慣

程式沒寫錯 但沒縮排沒空格閱讀起來較困難

#include<iostream> using namespace std; int main(){ int a,b,c; cin>>a>>b>>c; cout<<a+b+c<<"\n"; return 0;}

適時的空格與縮排有助於閱讀與除錯

#include <iostream> using namespace std; int main() { int a,b,c; cin >> a >> b >> c; cout << a + b + c << "\n"; return 0; }

四則運算

加減乘除
+ - * /
在 C++ 裡,四則運算大多就跟平常一樣
也遵從著先乘除後加減、括號先算的運算規則


程式碼

#include <bits/stdc++.h>
using namespace std;

int main() {
	int a = 7, b = 4;
	cout << "a + b = " << a + b << "\n";
	cout << "a - b = " << a - b << "\n";
	cout << "a * b = " << a * b << "\n";
	return 0;
}

執行結果

a + b = 11
a - b = 3
a * b = 28

練習題:ZJ a002,d049,d063
回家練習時點擊此連結若出現錯誤
請先登入你創好且已加入我們社團課程的帳號
就能看到題目囉


除法呢?


程式碼

#include <bits/stdc++.h>
using namespace std;

int main() {
	int a = 7, b = 4;
	cout << "a / b = " << a / b << "\n";
	return 0;
}

執行結果


執行結果:1.75 1

a / b = 1

記住:整數int的除法只取整數部分
小數點後面都省略


但如果想保留小數呢?

這留到下一次上課再介紹另一個變數型別

浮點數(float,double)


注意:使用除法不可除以 0

在數學中 除以零是一個沒有定義的值
在程式中也是 執行時會出現
RE (Runtime Error):程式碼停止運行


如何求餘數?

運算符 %可以求餘數
此為模運算 唸作 MOD
請不要唸 趴


求 A 除以 B的餘數

= A % B

程式碼

#include <bits/stdc++.h> using namespace std; int main() { int a = 12, b = 5; cout << "a % b = " << a % b << "\n"; return 0; }

執行結果

a % b = 2

練習題:ZJ d827

求餘數也可以用在很多地方
例如:判斷奇偶數、判斷是否為某數的倍數
下一次上課講到判斷式的時候會教


賦值運算

運算之後把結果賦值給變數

a = a + b;
a = a - b;
a = a * b;
a = a / b;

賦值運算子

可以不用賦值+運算
直接用賦值運算子就能解決

  • +=
  • -=
  • *=
  • /=

可以使用賦值運算子簡化程式碼

  • 使用賦值運算子
a = a + b; a = a - b; a = a * b; a = a / b;
  • 使用賦值運算子
a += b; a -= b; a *= b; a /= b;

遞增遞減運算子

i = i + 1;
i = i - 1;

可以簡化成

i += 1;
i -= 1;

又可以簡化成

i++;
i--;

第三種用法只限於 \(\pm1\)
關於前置與後置 請至延伸知識 有時間才會講


延伸知識與課外補充

  • 更詳細的介紹基本架構
  • 如何把負數轉成正數(絕對值)
  • 如何讓你的程式更有效率
  • 另一種輸入輸出方式 scanf / printf
  • IO 加速
  • C++ 如何讀取一整行
  • 比較 C++ 與 Python 的輸入規則
  • Python 如何以空白作為輸入
  • 許功蓋問題

更詳細的介紹基本架構

  1. 標頭檔 include
  2. 標準命名空間
  3. 主函式 main
  4. 深入瞭解

1. 標頭檔

#include <iostream> // 導入標頭檔,裡面包含輸出函式(cout)

2. 標準命名空間

using namespace std; // 使用標準命名空間,簡化接下來的程式碼

不使用命名空間

#include <iostream> int main() { int x, y; std::cin >> x >> y; std::cout << "x = " << x << "\ny = " << y << "\n"; return 0; }

使用命名空間

#include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; cout << "x = " << x << "\ny = " << y << "\n"; return 0; }

主函式 main

C++ 執行程式時會先跑主函式
也可以在主函式裡呼叫其他自訂函式
之後的社課會教到

#include <iostream> using namespace std; int functionA() { } int main() { functionA(); return 0; }

如何把負數轉成正數(絕對值)

想把負數轉成正數輸出時
可以用 abs 函式 (absolute value 縮寫)

cout << abs(-12) << "\n";

output

12

練習題:ZJ a799


想深入了解更多關於基本架構的解說
可回家點開這篇來參考:
C++ 骨幹的解說 by 南一中資研社師 SA


如何讓你的程式更有效率

在競程中,建議用 cout << "\n"; 來輸出換行
endl 用在 cout 輸出換行時
它會比單純的 \n 做更多細節處理
平常使用是更安全,但在競程反而會拖慢效率
拖慢效率的主因是 endl 自帶 flush
有興趣的人可以課後點這篇的前半段來看更深入的內容
落差與常識的補完 by SA


課外知識:另一種輸入輸出方式

scanf / printf

給有興趣的人去了解這篇
C++ 的輸出入 cin / cout 和 scanf / printf 誰比較快?
上課主要以 cin >> / cout << 為主


課外知識:IO 加速

如果你的程式上傳到 OJ 莫名其妙的出現 TLE
可以使用下面兩行來關閉 cin/cout 與
scanf()/printf() 之間的同步,導致其無法並用
大幅提升 cin / cout 的效能

ios::sync_with_stdio(0);
cin.tie(0);

上學期的課程幾乎都不會用到這個技巧
下學期在上演算法的時候才會出現用到的情況


C++ 如何輸入一整行


C++ 輸入規則:
一個空格或換行 為一個輸入

1 23 456 78 9
876 54 3 21

共有 9 個輸入


用 getline 輸入一整行

#include <iostream> using namespace std; int main() { string a, b; getline(cin,a); getline(cin,b); cout << "a = [" << a << "]\nb = [" << b << "]\n"; return 0; }

input

1 23 456 78 9
876 54 3 21

output

a = [1 23 456 78 9]
b = [876 54 3 21]

因為一行為一個輸入
所以總共有兩個輸入


比較 C++ 與 Python 的輸入規則

C++ Python 輸入規則
cin >> ? 以空白
getline(cin,a) input() 以整行

課外補充:

給有學Python但不知道怎麼以空白讀入整數的人

  1. 用 split + map
nums = list(map(int,input().split()))
  1. 用 split + for list
nums = [int(i) for i in input().split()]

課外補充:許功蓋問題

由於涉及編碼(Big5、utf-8)相關知識
所以課堂不細講 當作課外補充給有興趣的人去了解
許功蓋問題


課程回饋

南附資研第二次社課結束
感謝各位願意耐心聽完這次的社團課程
請社員們花一點時間填寫回饋表單
讓我們知道你們的想法及建議 謝謝大家

Select a repo