暑假資讀[1]
陳澔樂 & 數資25
介紹
- 225
- 班上充滿學術長
(學弟加電研,還有魔方) - 因為想學語法所以來當講師
競賽介紹
主線任務
校內能力競賽
北市賽
全國賽
選訓營 1!
選訓營 2!
國際資奧 IOI
海選 or APCS
初選
亞太資奧 APIO
11人
12人
20人
10人
10人
4人
支線任務
-
APCS
-
NPSC
-
YTP
-
ISSC
-
HP codewars
目的:
好玩
升學
Online Judge
寫題目的地方
*Codeforces 和 Atcoder 還有定期線上比賽
帳號設定
TIOJ 自己去搞
(可以用一個酷酷的motto 可用LaTex
Zerojudge 學校設建中
Codeforces Atcoder 建議現在就開
國籍設中華民國
學校設建中(注意CF上有兩個 選比較多人的
(你就可以開始電爛學長了
- AC(Accept)
- WA(Wrong Answer)
- TLE(Time Limit Exceed)
- MLE(Memory Limit Exceed)
- RE(Runtime Error)
- CE(Compile Error)
條件判斷
(Che is smart )==true
布林判斷式
回傳一個bool
1 == true == 真
0 == false == 假
常見運算子 | == | != | > | < |
---|---|---|---|---|
作用 | 等於 | 不等於 | 大於 | 小於 |
<= | >= | ! | && | || |
小於等於 | 大於等於 | 否 (1變0,0變1) |
且 | 或 |
飯粒
1 + 2 == 3 // true
1 + 2 == 4 // false
1 + 2 != 3 // false
1 + 2 != 4 // true
!(1 && 1) // false
(0 || 1) // true
注意事項:運算順序
字太小?
幫你整理:
< <= >= > |
---|
== != |
&& |
|| |
= (注意!不是布林運算子!) |
()
好用東西-->
if, else, else if
if
if (條件式) {
cout << "條件式為true時會印出這一行" << endl;
}
else
if (條件式) {
cout << "條件式為true時會印出這一行" << endl;
} else {
cout << "條件式為false時會印出這一行" << endl;
}
else if
// A, B 皆為條件式
if (A) {
cout << "A 為 true" << endl;
} else if (B) {
cout << "A 為 false 但是 B 為 true" << endl;
} else {
cout << "A、B 都是 false" << endl;
}
經典範例
#include <iostream>
using namespace std;
int main() {
int score; cin >> score;
if (score >= 80) cout << "AaW不可能是電神一定是成績改錯了\n";
else if (score >= 60)
cout << "好扯竟然有及格\n"; // 注意:以上兩種寫法if只會包含一行
else if (score >= 40) {
cout << "快去準備補考\n";
}
else {
cout << "沒救了QAQ\n";
}
}
AaW的物理成績實在太爛了,面臨補考邊緣。已知建中學期總成績60分以上為及格,40~59分要參加補考,39分以下就被死當了QAQ。又這一次物理老師成績打法心狠手辣,如果有辦法拿到80分以上就算是大電神。
但是AaW小學數學沒有學好,請幫他判斷他的成績算是哪個範圍呢?
switch case
switch(變數/式子){
case 可能1: //符合可能1
做事;
break; // 沒有break會繼續執行!!!
case 可能2: //符合可能2
做事;
break;
default: //上面的可能都沒符合
做事;
break;
}
switch case
int a;
cin >> a;
switch(a){
case 100:
cout << "a==100" << endl;
break;
case 200:
cout << "a==200" << endl;
// 沒有break
case 300:
cout << "a==200 or a==300" << endl;
break;
default: //上面的可能都沒符合
cout << "a不是100, 200, 300" << endl;
break;
}
三元運算子
A? x: y
當A為true回傳x
否則回傳y
int a = 12;
int b = ((a==12)? 23: 24); // b == 23
int c = ((a==14)? 33: 66); // c == 66
題目
有多筆測資部分等等會解釋要怎麼處理
題解
#include <iostream>
using namespace std;
signed main(){
long long a, b, c;
while(cin >> a >> b >> c) {
if (a+b>c && b+c>a && a+c>b) cout << "SAFE"<<endl;
else cout << "BYE" << endl;
}
return 0;
}
任兩邊和大於第三邊
#include <iostream>
using namespace std;
signed main(){
int a, b, c;
cin >> a >> b >> c;
if(a == b && b == c && a * b * c != 0) cout << "both";
else if(a * c == b * b && a * b * c != 0) cout << "geometric";
else if(a + c == b + b) cout << "arithmetic";
else cout << "normal";
return 0;
}
要注意等比級數部分,不可以有0
loops
迴圈
人生啊
用途
直接看例題:
No Judge:
給一個正整數N
輸出N個"*"
CODE
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
for(int i=0;i<n;i++){
cout<<"*";
}
return 0;
}
迴圈
用途
重複某件事情
兩大迴圈
for
for (起始; 終止條件; 更新) {
// 注意是用分號隔開
// do something...
}
範例
輸出從0 ~ 9
#include <iostream>
using namespace std;
signed main(){
int n = 10;
for (int i = 0; i < n; ++i) {
cout << i << " ";
}
cout << endl;
return 0;
}
範例
輸出從1 ~ 10
0 1 2 3 4 5 6 7 8 9
#include <iostream>
using namespace std;
signed main(){
int n = 10;
for (int i = 1; i <= n; ++i) {
cout << i << " ";
}
cout << endl;
return 0;
}
1 2 3 4 5 6 7 8 9 10
二維迴圈
#include <iostream>
using namespace std;
signed main(){
for (int i = 1; i <= 9; ++i) {
for (int j = 1; j <= 9; ++j) {
cout << i*j << " ";
}
cout << endl;
}
return 0;
}
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
while迴圈
while (A) { // A 為一個boolean expression
// A == true
// do something
}
// A == false
當表示式為真,不斷重複執行
和if的差別
while 內會一直重複,if 只會執行一次
飯粒
#include <iostream>
using namespace std;
signed main(){
int a = 12;
while (a < 23) {
cout << a << " ";
a = a + 3;
}
cout << endl << "after while: a=" << a << endl;
return 0;
}
12 15 18 21
after while: a=24
同場加映:do while
please enter password:
wrong password
please enter password:
wrong password
please enter password:
password correct
管你三七二十一,先做再說
至少會被執行一次!
#include <iostream>
#include <string>
using namespace std;
int main() {
string password = "aawsoweak";
string userinput;
do {
cout << "please enter password: ";
cin >> userinput;
if (userinput != password) cout << "wrong password\n";
} while (userinput != password);
cout << "password correct\n";
}
please enter password:
password correct
brineorz
8wcp
aawsoweak
aawsoweak
無限迴圈
while (true) {
// do sth
}
這樣不就永遠卡住了嗎?怎麼辦?
卡在廁所迴圈的救星
break
直接跳出去
while (條件) {
if (想要提早跳出) {
break;
}
// do sth
}
// break 完會跑到這邊
只想跳過一次怎麼辦?
continue
跳到下一次迴圈
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 5; ++i) {
if (i == 3) {
cout << "continue executed!\n";
continue;
}
cout << "i = " << i << endl;
}
}
i = 1
i = 2
continue executed!
i = 4
i = 5
continue vs break
while (/*...*/) { // continue 會回到這裡
if (sth) continue;
if (sth) break;
// do sth
}
// break 會直接跳出到這裡
補坑
多筆測資讀到EOF?
例子:zj a004
int n;
while (cin >> n) {
// do sth
}
手動輸入測試時,可以用ctrl + D 代替EOF
補坑
多筆測資讀到n==0?
int n;
cin >> n;
while (n != 0) {
// do sth
cin >> n;
}
int n;
while (cin>>n && n) {
//do sth
}
題目
while 和 for 都會用到喔!
更多例題
Array
Storing a lot of data
Problem A-1
You are given three numbers, find the largest one among them.
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
if (a > b) {
if (a > c) {
cout << a;
} else {
cout << c;
}
} else {
if (b > c) {
cout << b;
} else {
cout << c;
}
}
}
Problem A-1
The last appoach is terrible, don't follow
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
int max = -420;
if (a > max) {
max = a;
}
if (b > max) {
max = b;
}
if (c > max) {
max = c;
}
}
Problem A-2
You are given 100 numbers, find the largest one.
#include <iostream>
using namespace std;
int main() {
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61, a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76, a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91, a92, a93, a94, a95, a96, a97, a98, a99, a100;
cin >> a1 >> a2 >> a3 >> a4 >> a5 >> a6 >> a7 >> a8 >> a9 >> a10 >> a11 >> a12 >> a13 >> a14 >> a15 >> a16 >> a17 >> a18 >> a19 >> a20 >> a21 >> a22 >> a23 >> a24 >> a25 >> a26 >> a27 >> a28 >> a29 >> a30 >> a31 >> a32 >> a33 >> a34 >> a35 >> a36 >> a37 >> a38 >> a39 >> a40 >> a41 >> a42 >> a43 >> a44 >> a45 >> a46 >> a47 >> a48 >> a49 >> a50 >> a51 >> a52 >> a53 >> a54 >> a55 >> a56 >> a57 >> a58 >> a59 >> a60 >> a61 >> a62 >> a63 >> a64 >> a65 >> a66 >> a67 >> a68 >> a69 >> a70 >> a71 >> a72 >> a73 >> a74 >> a75 >> a76 >> a77 >> a78 >> a79 >> a80 >> a81 >> a82 >> a83 >> a84 >> a85 >> a86 >> a87 >> a88 >> a89 >> a90 >> a91 >> a92 >> a93 >> a94 >> a95 >> a96 >> a97 >> a98 >> a99 >> a100;
int max = 0;
if (a1 > max) {
max = a1;
}
if (a2 > max) {
max = a2;
}
if (a3 > max) {
max = a3;
}
if (a4 > max) {
max = a4;
}
if (a5 > max) {
max = a5;
}
if (a6 > max) {
max = a6;
}
if (a7 > max) {
max = a7;
}
if (a8 > max) {
max = a8;
}
if (a9 > max) {
max = a9;
}
if (a10 > max) {
max = a10;
}
if (a11 > max) {
max = a11;
}
if (a12 > max) {
max = a12;
}
if (a13 > max) {
max = a13;
}
if (a14 > max) {
max = a14;
}
if (a15 > max) {
max = a15;
}
if (a16 > max) {
max = a16;
}
if (a17 > max) {
max = a17;
}
if (a18 > max) {
max = a18;
}
if (a19 > max) {
max = a19;
}
if (a20 > max) {
max = a20;
}
if (a21 > max) {
max = a21;
}
if (a22 > max) {
max = a22;
}
if (a23 > max) {
max = a23;
}
if (a24 > max) {
max = a24;
}
if (a25 > max) {
max = a25;
}
if (a26 > max) {
max = a26;
}
if (a27 > max) {
max = a27;
}
if (a28 > max) {
max = a28;
}
if (a29 > max) {
max = a29;
}
if (a30 > max) {
max = a30;
}
if (a31 > max) {
max = a31;
}
if (a32 > max) {
max = a32;
}
if (a33 > max) {
max = a33;
}
if (a34 > max) {
max = a34;
}
if (a35 > max) {
max = a35;
}
if (a36 > max) {
max = a36;
}
if (a37 > max) {
max = a37;
}
if (a38 > max) {
max = a38;
}
if (a39 > max) {
max = a39;
}
if (a40 > max) {
max = a40;
}
if (a41 > max) {
max = a41;
}
if (a42 > max) {
max = a42;
}
if (a43 > max) {
max = a43;
}
if (a44 > max) {
max = a44;
}
if (a45 > max) {
max = a45;
}
if (a46 > max) {
max = a46;
}
if (a47 > max) {
max = a47;
}
if (a48 > max) {
max = a48;
}
if (a49 > max) {
max = a49;
}
if (a50 > max) {
max = a50;
}
if (a51 > max) {
max = a51;
}
if (a52 > max) {
max = a52;
}
if (a53 > max) {
max = a53;
}
if (a54 > max) {
max = a54;
}
if (a55 > max) {
max = a55;
}
if (a56 > max) {
max = a56;
}
if (a57 > max) {
max = a57;
}
if (a58 > max) {
max = a58;
}
if (a59 > max) {
max = a59;
}
if (a60 > max) {
max = a60;
}
if (a61 > max) {
max = a61;
}
if (a62 > max) {
max = a62;
}
if (a63 > max) {
max = a63;
}
if (a64 > max) {
max = a64;
}
if (a65 > max) {
max = a65;
}
if (a66 > max) {
max = a66;
}
if (a67 > max) {
max = a67;
}
if (a68 > max) {
max = a68;
}
if (a69 > max) {
max = a69;
}
if (a70 > max) {
max = a70;
}
if (a71 > max) {
max = a71;
}
if (a72 > max) {
max = a72;
}
if (a73 > max) {
max = a73;
}
if (a74 > max) {
max = a74;
}
if (a75 > max) {
max = a75;
}
if (a76 > max) {
max = a76;
}
if (a77 > max) {
max = a77;
}
if (a78 > max) {
max = a78;
}
if (a79 > max) {
max = a79;
}
if (a80 > max) {
max = a80;
}
if (a81 > max) {
max = a81;
}
if (a82 > max) {
max = a82;
}
if (a83 > max) {
max = a83;
}
if (a84 > max) {
max = a84;
}
if (a85 > max) {
max = a85;
}
if (a86 > max) {
max = a86;
}
if (a87 > max) {
max = a87;
}
if (a88 > max) {
max = a88;
}
if (a89 > max) {
max = a89;
}
if (a90 > max) {
max = a90;
}
if (a91 > max) {
max = a91;
}
if (a92 > max) {
max = a92;
}
if (a93 > max) {
max = a93;
}
if (a94 > max) {
max = a94;
}
if (a95 > max) {
max = a95;
}
if (a96 > max) {
max = a96;
}
if (a97 > max) {
max = a97;
}
if (a98 > max) {
max = a98;
}
if (a99 > max) {
max = a99;
}
if (a100 > max) {
max = a100;
}
cout << max << '\n';
}
Problem A-3
You are given 1000000 numbers, find the largest one.
WTF no
Problem A-3
#include <iostream>
using namespace std;
int main() {
int a[100000];
for (int i = 0; i < 100000; i++) {
cin >> a[i];
}
int max = 0;
for (int i = 0; i < 100000; i++) {
if (a[i] > max) max = a[i];
}
cout << max << '\n';
}
Simpler right?
Initializing an array
#include <iostream>
using namespace std;
int main() {
int a[] = {0,1,2,3,4,5,6,7,8,9};
int b[10] = {0,1,2,3,4,5,6,7,8,9};
int c[10] = {0};
int d[10];
cout << d[4] << '\n'; // what will happen here?
int e[] = {0};
}
multi-dimensional array
#include <iostream>
using namespace std;
int main() {
int twoD[3][9];
int threeD[4][20][69];
int fourD[7][1][2][2];
// ...
}
variable-sized array
#include <iostream>
using namespace std;
int main() {
int length;
cin >> length;
int arr[length];
for (int i = 0; i < length; i++) {
cin >> arr[i];
}
for (int i = 1; i < length; i++) {
arr[i] += arr[i - 1];
}
length = 800;
cout << arr[420] << '\n'; // what will happen here?
}
Array with uniform initial value
#include <iostream>
using namespace std;
int main() {
int length, value;
cin >> length >> value;
int arr[length] = {value};
for (int i = 0; i < length; i++) {
cout << arr[i] << '\n';
}
}
Doesn't work, does it?
Array with uniform initial value
#include <iostream>
using namespace std;
int main() {
int length, value;
cin >> length >> value;
int arr[length];
for (int i = 0; i < length; i++) {
arr[i] = value;
}
}
bUT tHiS lOoKs LaMe!!!11!111!!
A better array
#include <iostream>
#include <vector>
using namespace std;
int main() {
int length, value;
cin >> length >> value;
vector<int> arr(length, value);
for (int i = 0; i < length; i++) {
cout << arr[i] << '\n';
}
}
Fabulous!
vector vs. array
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a1[] = {1, 2, 3};
vector<int> v1_1 = {1, 2, 3};
vector<int> v1_2{1, 2, 3};
int a2[100];
vector<int> v2(100);
int a3[5] = {1, 1, 1, 1, 1};
vector<int> v3(5, 1);
}
simple tools to change a vector
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
v.resize(10);
for (int i = 0; i < 10; i++) {
cout << v[i] << '\n';
}
v.resize(20, 12);
for (int i = 0; i < 20; i++) {
cout << v[i] << '\n';
}
v.resize(3);
for (int i = 0; i < 3; i++) {
cout << v[i] << '\n';
}
v.assign(6, 9);
for (int i = 0; i < 6; i++) {
cout << v[i] << '\n';
}
v = {1, 3, 2};
cout << v.size() << '\n';
cout << v.front(); // == v[0]
cout << v.back(); // == v[v.size() - 1]
v.pop_back();
cout << v.size() << '\n';
v.push_back(9);
cout << v.back() << '\n';
}
if i were hated by you
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v(10, 1);
for (int i = 1; i < v.size(); i++) {
v[i] += v[i - 1];
}
// for (int i = 0; i < v.size(); i++)
for (int& n: v) {
cout << n << '\n';
}
}
multi-dimensional vector
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector< vector<int> > ddv1;
vector<int> ddv2[100];
}
How to initialize?
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector< vector<int> > ddv1(100, vector<int>(69, 34));
vector<int> ddv2[100];
for (auto& v: ddv2) {
v.assign(69, 34);
}
}
That's it!
More detailed syntax and usage will be in the future lessons
例題
比較難的例題
複雜度
這段程式好複雜喔??
對於兩個程式,我要比較誰更好一點
那,什麼是好?
- 時間迅雷不及掩耳
-
少少的空間
- 正確率高
- 打起來方便快速
比賽中關注前兩個居多
- Time Complexity
- Space Complexity
複雜度就是拿來衡量演算法的時空效率
怎麼測量???
實測當然最準
但這樣我們會浪費時間寫慢的程式碼
寫之前我只需要估計不就好了?
複雜度記法
有很多種標準,通常我們會看O-notation
代表一個演算法的時間上界
O(f(n)),代表演算法因為n的時空成長率不比f(n)慢
原則
一些栗子
常見複雜度量級
空間複雜度也是一樣概念
看一些code
MINIMAL
找最大值
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; cin>>n;
int arr[n];
//input the elements in the array
int maxn = -1;
for (int i = 0; i < n; ++i) {//find the max element
maxn = max(maxn,arr[i]);
}
cout<<maxn<<endl;
return 0;
}
Time complexity : O(n)
MINIMAL
插入排序
void insertion_sort(vector <int> &arr) {
for (int i = 0; i < n-1; ++i) {
int minnum = arr[i];
int index = i;
for (int j = i+1; j < n; ++j) {
if (minnum > arr[j]) {
index = j;
minnum = arr[j];
}
}
swap(arr[i],arr[index]);
}
}
Best case:O(n)
Worst case:O(n^2)
Complexity:O(n^2)
均攤複雜度
- 平常都是一樣,但是某些情況會不同
- vector的push_back
- 平常O(1),做n次偶爾O(n)
- 阿那平均還是O(1)嘛
平均??
- 假設我們平常插入是O(1)
- 做n次插入時有一次是O(n)
- 即插入n個元素,做了n量級的操作次數
- 均攤下來做一次插入的時間還是O(1)
暑假資讀
By Willy Chan
暑假資讀
- 427