Dev-C++
codeblocks
#include <iostream>
using namespace std;
int main(){
cout << "Hello, world!\n";
}
建議全部自己打一次
引入已經寫好的程式 像cout
把std::cout變成cout
程式一開始進入的地方
儲存資料的東西
整數
範圍:
~
佔用空間: 4 Bytes
浮點數
精準至小數點後七位
佔用空間: 4 Bytes
字元
佔用空間: 1 Bytes
用ASCII碼儲存
' '表示一個字元
整數
範圍:
~
佔用空間: 4 Bytes
浮點數
精準至小數點後七位
佔用空間: 4 Bytes
字元
佔用空間: 1 Bytes
用ASCII碼儲存
' '表示一個字元
字串
可以儲存多個字元
" "表示一個字串
布林(真假)值
儲存true(1)和false(0)
佔用空間: 1 Bytes
//變數型別 變數名稱;
int x = 0;
float y = 1.5;
char c = 'c';
bool b = 1;
string s = "Hello, world!";
#inculde<iostream>
using namespace std;
int main(){
int a, b;
cin>>a>>b;
cout<<"a:"<<a<<" b:"<<b<<'\n';
}
int x;
x = 3;
x = 2 + 5;//x = 7
x = x - 1;//x = 6
x = 3 * x;//x = 18
x = x / 5;//x = 3
x = x % 3;//x = 0
+ 加
- 減
* 乘
% 取餘
/ 除
整數/整數是取商
= 指定
()括號
int x;
x = 3;
cout<<x++<<'\n';//cout 3, x = 4
cout<<++x<<'\n';//cout 5, x = 5
x -= 1;
x *= 3;
x %= 2;
++ 遞增
-- 遞減
運算後指定
輸入身高(公分)、體重(公斤),計算出BMI
Sample Input
180 70
Sample output
21.6049
輸入秒,將秒轉換成 小時:分鐘:秒 的格式輸出
Sample Input
350
3601
19855
Sample output
0:5:50
1:0:1
5:30:55
< 小於
> 大於
<= 小於等於
>= 大於等於
==相等
(注意不是=)
!=不相等
if(條件){
你要執行的東西
}
例如:
int a = 5, b = 4;
if(a > b){
cout<<"a > b\n";
}
&& 邏輯AND
|| 邏輯OR
! 邏輯NOT
AND和OR可以用來連接兩個條件
A&&B | B = TRUE | B = FALSE |
---|---|---|
A = TRUE | TRUE | FALSE |
A = FALSE | FALSE | FALSE |
A||B | B = TRUE | B = FALSE |
---|---|---|
A = TRUE | TRUE | TRUE |
A = FALSE | TRUE | FALSE |
- | A = TRUE | A = FALSE |
!A | false | true |
int a;
cin>>a;
if(4 <= a && a < 7){
cout<<"4 <= a < 7\n";
}
if(4 <= a < 7){
cout<<"4 <= a < 7\n";
}
bool結果只有 1 or 0
/*當上方的if(else if)的條件判斷是false時
才會判斷(執行)下面的else if(else)*/
int a, b;
cin>>a>>b;
if(a>b){
cout<<"a>b\n";
}
else if(a<b){
cout<<"a<b\n";
}
else{
cout<<"a==b\n";
}
INPUT
OUTPUT
75 90 80 70 60
66 80 68 67 66
99 100 98 50 40
乙
丙
甲
讓程式重複執行
while
int i,n;
cin>>n;
i=0;
while(i<n){
cout<<i<<' ';
i++;
}
while(條件){
要執行的東西;
}
int n;
cin>>n;
for(int i=0;i<n;i++){
cout<<i<<' ';
}
for(第一次進入;條件;每次結束){
}
1
3
2
4
5
int n;
cin>>n;
while(1){
cout<<i++<<' ';
if(i>=n) break;
}
跳出迴圈
5
10 -1 25 33 -20
2
1 1
33 -20
1 1
輸入
如果 是奇數
如果 是偶數
輸出過程中 的數值直到
INPUT
3
4
OUTPUT
3 10 5 16 8 4 2 1
4 2 1
輸入 印出 階寬度 高度 的階梯
----
----
----
----
----
----
--
--
--
--
--
--
輸入 依照範例輸出印出大小 的圖形
為奇數
...
...
...
.#.#.
#...#
.....
#...#
.#.#.
.##.##.
#.#.#.#
##...##
.......
##...##
#.#.#.#
.##.##.
可以儲存很多變數的東西
string 是一種陣列
其實就是加個中括號
變數型別 變數名稱[陣列大小];
int a[100];
string s[100];
char c[10000];
bool b[10];
int a[5]={0,1,2,3,4};
string s[2]={"Hello","ABC"};
指定預設值
在函數內沒指定值時會爛掉
但放全域會幫你設預設值
放函數內約可開幾百萬
放全域可以開到千萬
int a[100];
for(int i=0;i<100;i++){
cin>>a[i];
}
for(int i=0;i<100;i++){
cout<<a[i]<<' ';
}
陣列的索引從0開始
所以如果陣列大小是n,可用範圍就是0~n-1
int a[100][100];
char c[50][50][50];
INPUT
第一行有兩個正整數n q
第二行有n個整數代表數列A的值
接下來有q行,每一行有兩個正整數i j
代表要交換的數的編號
編號從1開始
OUTPUT
輸出操作後的數列
給一個數列A,接著有q個操作每次操作會交換數列裡的兩個編號的數,在最後輸出操作後的數列
5 4
5 4 2 3 1
1 3
1 2
3 4
1 5
1 2 3 5 4
給定一個字串S與一個正整數k,將字串的每個字變成該英文字母的後k個,如果字母順序+k>z,從a繼續。
INPUT
第一行一個n代表字串長度與一個k
第二行有一個字串,保證每個字元皆為小寫英文字母
OUTPUT
輸出加密文字
5 2
abcde
6 5
abcxyz
cdefg
fghcde
眾數的定義是在一個數列出現次數最多的數
給定一個數列並找出它的眾數
INPUT
第一行一個正整數n代表數列長度
第二行有n個數,代表數列的值
OUTPUT
輸出眾數
5
3 2 2 2 1
10
9 9 8 3 4 7 1 3 4 9
2
9
回傳類型 函數名稱(參數類別 參數名稱,...){
return 要回傳的東西;
}
int add(int a,int b){
return a+b;
}
#include<iostream>
#include<cmath>
struct Point{
int x,y;
double length(){
return sqrt(x*x+y*y);
}
};
int main(){
Point a;
cin>>a.x>>a.y;
cout<<a.length()<<'\n';
}
自己呼叫自己
像這樣
int f(int n){
if(n==1||n==2) return 1;
return f(n-1)+f(n-2);
}
要記得加終止條件
先看例題
枚舉所有的子集的和
執行次數(時間複雜度)
先進後出
先進先出
每次把區間切半
bool f(int l,int r,int x){
while(l<r){
int m=(l+r)/2;
if(a[m]==x) return 1;
if(a[m]<x) l=m+1;
else r=m-1;
}
return 0;
}
#include<algorithm>
很多好用的內建函式
min()、max()、sort()、lower_bound()
儲存變數位址的變數
int* a;
char *c;
int a=5;
int* p=&a;
cout<<*p;//5
(*p)++;
cout<<*p;//6
分配記憶體給指標
int *p=new int;
char* c=new char;
int *a=new int[100];
int *p=new int;
delete p;
取別的變數名
int a=5;
int& b=a;
cout<<b;//5
b++;
cout<<a;//6
將n塊錢換成面額 1、5、10、50的硬幣
求最少換到的硬幣數
排序後greedy
宣告:priority_queue<int> 取最大值
priority_queue<int,vector<int>,greater<int>> 取最小值
top() 裡面的最大(小)值
pop() 刪除最大(小)值
可以取最大值的東西
#include<queue>
#include<iostream>
#include<queue>
using namespace std;
int main(){
priority_queue<int> pq;
pq.push(1);
pq.push(3);
cout<<pq.top()<<'\n';//3
pq.pop();
cout<<pq.top()<<'\n';//1
}
比較難的greedy
分成小問題解決
再合併
算
int POW(int x,int p){
int ans=1;
for(int i=0;i<p;i++) ans*=x;
return ans;
}
算
把p分成兩半
如果p為奇數再乘x
int fpow(int x,int p){
if(p==1) return x;
if(p==0) return 1;
int res=fpow(x,p/2);
res*=res;
if(p%2==1) res*=x;
return res;
}
把一個數列切成兩半
然後合併
int a[N],t[N];
void m_sort(int l,int r){
if(l==r) return;
int m=(l+r)/2,i,j,cnt;
m_sort(l,m),m_sort(m+1,r);
for(i=l,j=m+1,cnt=0;i<=m&&j<=r;){
if(i<=m&&(j>r||a[i]<=a[j])) t[cnt]=a[i],i++,cnt++;
if(j<=r&&(i>m||a[j]<=a[i])) t[cnt]=a[j],j++,cnt++;
}
for(i=l;i<=r;i++)
a[i]=t[i-l];
}
如果i有一條邊連向j
a[i][j]=1
否則
a[i][j]=0
把跟點i相鄰的點放進a[i]
vector<int>adj[N];
bool vis[N];
void dfs(int v){
vis[v]=1;
for(int u:adj[v])
if(!vis[u]) dfs(u);
}
給你一個圖,邊的長度皆為1,求起點s到終點t的最短距離
vector<int>adj[N];
int dis[N];
bool vis[N];
void bfs(int s){
queue<int> q;
dis[s]=0,vis[s]=1;
while(!q.empty()){
int v=q.front();
q.pop();
for(int u:adj[v]){
if(vis[u]) continue;
vis[u]=1;
dis[u]=dis[v]+1;
q.push(u);
}
}
}
記得BFS嗎
A
B
C
D
F
E
G
20
1
7
4
5
1
3
5
3
A
B
C
D
F
E
G
+1
+7
+7
+7
+5
+8
bool vis[200010];
vector<pair<int,int> > adj[200010];
void dijkstra(int s){
priority_queue<pair<int,int> >pq;
pq.push({0,s});
while(!pq.empty()){
int w=pq.top().first,v=pq.top().second;
pq.pop();
if(vis[v]) continue;
vis[v]=1;
dis[v]=-w;
for(auto u:adj[v]){
pq.push({w-u.second,u.first});
}
}
}
B
D
C
E
F
A
令所有點塗上紅或綠色
判斷有沒有存在所有相鄰點對(u,v)的顏色皆不同的塗法
A
A
B
D
E
F
C
B
D
C
E
F
例題
A
B
C
D
F
E
H
20
1
7
4
5
1
3
5
3
A
B
C
D
F
E
H
A
B
C
D
F
E
H
A
B
C
D
F
E
H
A
B
C
D
F
E
H
20
1
7
4
5
1
3
5
3
A
B
C
D
F
E
H
A
B
C
D
F
E
1
3
4
5
2
7
6
A
B
C
D
F
E
A
B
C
D
F
E
F
A
B
C
D
E
F
A
B
C
D
E
F
A
B
C
D
E
A
B
C
D
E
A
B
C
D
E
int sz[N],top[N];
int find(int x){
if(top[x]==-1) return x;
top[x]=find(top[x]);//路徑壓縮
return top[x];
}
void Union(int u,int v){
u=find(u),v=find(v);
if(u==v)return;
if(sz[u]>sz[v]) swap(u,v);//啟發式合併
top[u]=v;
sz[v]+=sz[u];
}
A
C
B
D
E
F
DAG一定存在拓樸排序
A
C
B
D
E
F
100
200
400
50
為連通圖且邊數+1=點數