owned this note changed a year ago
Published Linked with GitHub

C++ 基礎II


複習


變數宣告:

int a = 1; long long b = 2; char c = 'a'; double d = 2.564; // 不要用 float ! string e = "ABC"; bool ck = 0; //false

注意事項

  • 請注意: int 範圍 (1e9) 如果超過請用 long long
  • char 字元使用 'c' 表示, string 字元 "hi oj"
  • 使用 string 而不使用 char[]

acill

  • 注意字元是 '' 字串是 ""
  • 不用打 97 來代表 a ,可以直接用 'a' 就好
char c; cin >> c; if ('a' <= c && c <= 'z') cout << "lower" << endl;

額外題目 X 2


你快樂嗎?

  • 型態判斷

進階天數判斷 (不要用 if else)

  • true(1) false(0)

迴圈


for

最常用的迴圈,語法如下:

for (int i = 0 ; i < 100 ; i++){ cout << i << '\n' ; // do things }

語法

for (1 ;2 ;4) { // 3 do }
  • 1: 程式執行到迴圈時,第一件會做的事情
  • 2: 程式進行的條件,如果不滿足,便會離開這個迴圈。
  • 3: 迴圈裡面做什麼事情
  • 4: 做完一件事情後,迴圈會做的事

反過來?

string a = "1234567890"; for (int i = a.length() - 1 ; i >= 0 ; i--) { cout << a[i]; }

注意事項

  • 如果是用在陣列裡,記得範圍 (尤其反向的時候)
  • 如果記得如果反向,要-1,如果寫成 +1 會無窮

巢狀迴圈

(多層迴圈)

for (int i = 0 ; i < 10 ; i++) { for (int j = 0 ; j < 20 ; j++) { // do ... } }

注意事項

  • 記得變數要設不一樣,最後要++的部分也要寫對

只想要條件的迴圈?

int n = 0; for( ; n < 10 ; ){ int x; cin >> x; n += x; }

while

用法如下:

while(條件){ //do }

剛剛的例子

while(n < 10){ int x; cin >> x; n += x; }

無窮迴圈

while 是條件成立會繼續執行,那如果條件本身就是 true 呢?

while (true) { // do }

但是你會發現,這樣的迴圈無法停止,於是我們需要引入讓迴圈結束的工具


continue/break

當我們遇到某些條件成立時,想跳出迴圈 or 進下一輪


continue

用來結束這一輪,但是迴圈會繼續執行

int x; cin >> x; for (int i = 0 ; i < x ; i++) { if (i % 2 == 0) continue; else cout << i << endl; }

break

用來直接結束當前迴圈

int x, now = 0; cin >> x; while (true) { if (now * now * now == x) break; now ++; } cout << now << '\n';

注意事項

  • 這兩個操作都只能夠離開當前的迴圈!
  • 用無窮迴圈記得要有 break 的離開條件

離開當前的迴圈?

以下錯誤寫法

int ans1, ans2; for (int i = 0 ; i < 10 ; i++) { for (int j = i + 1 ; j < 10 ; j++) { if (i * j > 78) { ans1 = i, ans2 = j; break; } } } cout << ans1 << " " << ans2 << endl;

正確寫法

int ans1, ans2; bool check = false; for (int i = 0 ; i < 10 ; i++) { for (int j = 0 ; j < 10 ; j++) { if (i * j > 78) { ans1 = i, ans2 = j; check = true; break; } } if (check) break; } cout << ans1 << " " << ans2 << endl;

練習題

  • B001
  • B002

image


題目的各種輸入方式


t筆輸入

int t; cin >> t; while (t--) { // do } // 如果題目要求輸出 case i for (int i = 1 ; i <= t ; i++) { cout << "Case " << i << " "; // do }

輸入直到讀到某個值

例如讀到 -1 為止

int t; cin >> t; while (true) { if (t == -1) break; // do cin >> t; }

輸入直到 EOF

EOF = end of file

int t; while (cin >> t) { // do }

輸出 n 個數字用空白隔開

要求: 尾巴不能有空白

int ans[10] = {2,3,4,1,5,6,7,1,2,3}; bool first = true; for (int i = 0 ; i < 10 ; i++){ if (first) { cout << ans[i]; first = false; }else{ cout << " " << ans[i]; } } cout << '\n';

這只是幾種常見的輸入輸出而已,還是要看題目的敘述為主。


陣列

如果要儲存5個變數,我們可能會這樣做

int a, b, c, d, e;

但如果100、1000個變數那怎麼辦呢?


宣告

int a[15]; //a[0]~a[14] 共15個 char b[150]; //b[0]~b[149] 共150個 double c[200]; //c[0]~c[199] 共200個 string str[1500]; //str[0]~str[1499] 共1500個

可以一次定義所有數字 or 部分數字

int a[5] = {1,2,3,4,5}; int b[100] = {1,2,3}; // 其餘會自動補 0 int zero[1000] = {0};

使用

int a[5] = {1,2,3,4,5}; cout << a[0] + a[2] << '\n'; a[3] = 6; cout << a[1] + a[3]; for (int i = 0 ; i < 5 ; i++) { // 注意 是 0~4 cout << a[i] << ' '; } cout << '\n';

注意事項

  • 陣列的 index (索引值) 是從 0 開始到 size - 1,引用超過會報 RE or WA。
  • 陣列宣告過後,不可改變大小或重新宣告。
  • 如果在裡面宣告沒有給定初始值,他不會自動幫你補 0 !!!
  • 陣列大小大概只能開到 2e6 左右

多維陣列

陣列是可以有多個維度的,例如:

int arr[13][14][15] = {0}; // 設0, cin >> arr[2][5][6]; cout << arr[2][5][6] << '\n'; // 也可以這樣定義,一樣不夠的會自動補 0 int arr[2][3] ={{1,2,3},{4,5,6}};

image


string


宣告

#include <string> #include <iostream> using namespace std; int main(void) { string s; cin >> s; for (int i = 0 ; i < s.length() ; i++) { // do... } }

好用的加法

string a = "123", b = "456"; string c = a + b; // 123456 cout << c << '\n';

好用的翻轉 string

#include <algorithm> // 記得記得要加 #include <string> #include <iostream> using namespace std; int main(void) { string s = "123456"; reverse(s.begin(), s.end()); }

酷酷的判斷

字串判斷大小是根據字典序排序,也就是根據 acill 碼來比較大小
他會先判斷最前面,依序往後面判斷

假設 a = "1234" b = "567"

則 b 比較大

假設 a = "12345" b = "123"
則 a 比較大

可以直接用 判斷寫法寫

string a = "abcd", b = "fghi"; cout << (a > b) << '\n'; // false

酷酷的標頭檔 (懶人)

#include <bits/stdc++.h>

包含

image


輸入輸出優化

檢定不會用到,但我提一下
請注意: 不要使用 endl 會導致使用 flush 而無法加快,請使用 '\n'

#include <bits/stdc++.h> using namesapce std; int main(void) { ios::sync_with_stdio(false),cin.tie(0); }

練習題

  • B003
  • B004

image


function


例子

#include <bits/stdc++.h> using namespace std; void hello() { cout << "hello world\n"; } int main(void) { hello(); }

引入變數

void two_sum (int a, int b) { cout << a + b << '\n'; } int main(void) { int x1, x2; cin >> x1 >> x2; two_sum (a, b); }

回傳不同型態

return

  • void 不回傳
  • int\char\string 回傳該型態
void nothing() { return; } int two_sum (int a, int b) { return a + b; } int main(void) { int x1, x2; cin >> x1 >> x2; cout << two_sum(x1,x2); }

前後定義的問題

int main(void) { int x1, x2; cin >> x1 >> x2; cout << two_sum(x1,x2); } int two_sum (int a, int b) { return a + b; }

image


解決方法

  • 定義在前面
  • 跟變數一樣 先宣告
int two_sum (int a, int b); int main(void) { int x1, x2; cin >> x1 >> x2; cout << two_sum(x1,x2); } int two_sum (int a, int b) { return a + b; }

我喜歡的寫法

#include <bits/stdc++.h> using namespace std; void solve() { // do } int main(void) { int t = 1; // cin >> t; while (t--) solve(); }

我喜歡的寫法 EOF 版本

#include <bits/stdc++.h> using namespace std; void solve(int t) { // do } int main(void) { int t; // 看題目輸入什麼型態 while (cin >> t) solve(t); }

why

  • 假設今天我們在好幾層迴圈的時候,得到答案想要離開 我們可能需要這樣寫
bool check = false; for (int i = 0 ; i < n ; i++) { for (int j = 0 ; j < m ; j++) { for (int k = 0 ; k < p ; k++) { if (...) { cout << ans << '\n'; check = true; break; } } if (check) break; } if (check) break; }

可以直接 return

for (int i = 0 ; i < n ; i++) { for (int j = 0 ; j < m ; j++) { for (int k = 0 ; k < p ; k++) { if (...) { cout << ans << '\n'; return; } } } }

區域、全域變數


區域變數

起始於變數宣告,結束於宣告敘述所在的區塊的大右括號。

#include <bits/stdc++.h> using namespace std; int func(int a, int b) { int c = 5; return c*(a+b); // abc都屬於func的區域變數 (和main的abc不衝突) }; int main(void){ int a, b; //屬於main函式的區域變數 cin >> a >> b; cout << func(a,b) << '\n'; for (int i = 0 ; i < 3 ; i++) { int x; //出了for迴圈之後,x就結束了 cin >> x; cout << x << '\n'; } }

全域變數

  • 宣告在所有區塊和類別之外的變數
  • 不可宣告同名的全域變數
  • 若沒有給定初始值,會自動給0

全域變數

#include <bits/stdc++.h> using namespace std; int arr[10000000]; //全域變數,所以沒有給定初始值會自動給0 int main(void){ int str[100000]; //這邊是區域變數,沒有給定初始值就不會有 }

注意事項

  • 定義名稱不要重複
  • 陣列大小區域大概 (2e6) 全域大概可以開到 (5e7)
  • 全域變數會自動給 0 但區域變數不會!!

練習題

  • B005

Select a repo