一業 葉子齊
- 引入函式庫<stack>
- 先進來 後出去
- 引入函式庫<queue>
- 先進來 先出去
push
pop
top
push
pop
front
| stack | 功能 |
|---|---|
| push(x) | 放入元素 |
| pop() | 刪除第一個元素 |
| top() | 讀取最上面的元素 |
| empty() | 是否為空 |
| size() | 內有幾個元素 |
| queue | 功能 |
|---|---|
| push(x) | 放入元素 |
| pop() | 刪除第一個元素 |
| front() | 讀取最前面的元素 |
| empty() | 是否為空 |
| size() | 內有幾個元素 |
stack/queue<型態>名稱;stack
queue
stack<int>SK;queue<int>QE;SK
QE
stack
queue
SK.push(A);
QE.push(A);
A
A
SK
QE
stack
queue
SK.push(B);
QE.push(B);
A
A
SK
QE
B
B
stack
queue
SK.push(C);
QE.push(C);
A
SK
QE
B
C
B
A
C
top
front
stack
queue
SK.pop();
QE.pop();
A
SK
QE
B
C
A
B
C
front
stack
queue
SK.pop();
QE.pop();
A
SK
QE
B
C
C
C
B
front
stack
queue
SK.pop();
A
SK
QE
B
C
C
C
front
stack
queue
A
SK
QE
B
C
C
C
empty
是空的 → 回傳1
不是空的(內含元素)→ 回傳0
回傳 1
回傳 0
stack
queue
A
SK
QE
B
C
C
A
B
size
內有幾個元素
回傳 0
回傳 2
| (回傳) | 空的 | 不是空的 |
|---|---|---|
| empty | 1 | 0 |
| size | 0 | 內含元素的數量 |
| (回傳) | 空的 | 不是空的 |
|---|---|---|
| empty | 1 | 0 |
| size | 0 | 內含元素的數量 |
輸入說明:第一行有一個 N(1≤N≤10^5) ,
接下來有 N 行,每一行一開始有一個 k ,代表哪一種操作:
如果 k=1 ,
請再讀入一個整數 x(1≤x≤109) ,並在堆疊頂端加入該整數。
如果 k=2 ,
請輸出堆疊最頂端的元素,
如果當前堆疊內沒有元素,請輸出 −1 。
如果 k=3 ,
請刪除堆疊最頂端的元素,
如果當前堆疊內沒有元素,請無視該操作。
範例輸入:
13
1 1
1 2
1 3
2
3
3
2
1 4
3
2
3
3
2
範例輸出:
3
1
1
-1
#include <iostream>
#include <stack>
using namespace std;
int main()
{
int n,k,a;cin>>n;
stack<int>s;
for(int i=0;i<n;i++){
cin>>k;
if(k==1){
cin>>a;
s.push(a);
}
else if(k==2){
if(s.size()==0){
cout<<"-1"<<endl;
}
else if(s.size()!=0){
cout<<s.top()<<endl;
}
}
else if(k==3 && s.size()!=0){
s.pop();
}
}
return 0;
}ios_base::sync_with_stdio(0);
cin.tie(0);打在int main()大括號裡
一群 林芊妘
Dynamic Programming 動態規劃
把大問題化成小問題,並且用陣列儲存起來
範例-費氏數列
| f(0) | f(1) | f(2) | f(3) | f(4) | f(5) |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 2 | 3 | 5 |
| f(6) | f(7) | f(8) | f(9) | f(10) | f(11) |
|---|---|---|---|---|---|
| 8 | 13 | 21 | 34 | 55 | 89 |
=> f(n) = f(n-1) + f(n-2)
範例-費氏數列
using namespace std;
#include <iostream>
int f(int num)
{
if (num==0) return 0;
else if (num==1) return 1;
else
{
int fib=f(num-1)+f(num-2);
return fib;
}
}
int main()
{
int n;
cin>>n;
cout<<f(n);
return 0;
}範例-費氏數列
f(5)
f(3)
f(3)
f(4)
f(2)
f(2)
f(1)
範例-費氏數列
using namespace std;
#include <iostream>
long long f(long long num)
{
long long dp[num+1];
dp[0]=0;
dp[1]=1;
for(int i=2;i<num+1;++i)
{
dp[i]=dp[i-1]+dp[i-2];
}
return dp[num];
}
int main()
{
int num;
cin>>num;
cout<<f(num);
return 0;
}範例-最短行徑
0 1 3 3
2 3 1 0
3 1 2 0
範例-最短行徑
1
1
1
4
3
1
1
1
0
2
3
4
6
10
10
20
範例-最短行徑
0 1 3 1
2 3 0 4
3 2 2 0
範例-最短行徑
0 1 3 1
2 3 0 4
3 2 2 0
範例-最短行徑
0 1 4 5
2 3 0 4
3 2 2 0
範例-最短行徑
0 1 4 5
2 3 0 4
5 2 2 0
範例-最短行徑
0 1 4 5
2 3 0 4
5 2 2 0
範例-最短行徑
0 1 4 5
2 4 0 4
5 2 2 0
範例-最短行徑
0 1 4 5
2 4 0 4
5 2 2 0
範例-最短行徑
0 1 4 5
2 4 0 4
5 6 2 0
範例-最短行徑
0 1 4 5
2 4 0 4
5 6 2 0
範例-最短行徑
0 1 4 5
2 4 4 4
5 6 2 0
範例-最短行徑
0 1 4 5
2 4 4 4
5 6 2 0
範例-最短行徑
0 1 4 5
2 4 4 4
5 6 6 0
範例-最短行徑
0 1 4 5
2 4 4 4
5 6 6 0
範例-最短行徑
0 1 4 5
2 4 4 8
5 6 6 0
範例-最短行徑
0 1 4 5
2 4 4 8
5 6 6 0
範例-最短行徑
0 1 4 5
2 4 4 8
5 6 6 6
範例-最短行徑
#include <bits/stdc++.h>
using namespace std;
int main()
{
int m,n;
cin>>m>>n;
int path[m][n];
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
cin>>path[i][j];
//輸入數值
}
for(int i=1;i<n;i++)
path[0][i]+=path[0][i-1]; //累加最上橫排
for(int i=1;i<m;i++)
path[i][0]+=path[i-1][0]; //累加最左直排
for(int i=1;i<m;i++)
{
for(int j=1;j<n;j++)
{
path[i][j]+=min(path[i-1][j],path[i][j-1]);
//找上方和左方的最小值並相加
}
}
cout<<path[m-1][n-1]<<endl;
return 0;
}爬樓梯
今天有個屁孩小明,他爬階梯時可以一次爬一格、三格或是五格,他們學校每半層樓梯有11格,請問他爬到4樓有幾種方法?
爬樓梯
#include <iostream>
using namespace std;
int dp[1000];
int main()
{
int step[3]={1,3,5};
dp[0]=1;
for(int i=0;i<3;i++)
{
for(int j=step[i];j<1000;j++)
dp[j]+=dp[j-step[i]];
}
int n=11,a=1;
for(int i=0;i<8;i++)
a*=dp[n];
cout<<a<<endl;
return 0;
}
一仁 蔡其霏
儲存很多個int / char 陣列
but…
要儲存一個int 和一個char 呢?
甚至...是要儲存陣列?
#include <iostream>
using namespace std;
struct checkup{
string name;
double height;
int weight;
double eyesight[2];
void BMI(){
cout << weight/(height*height) << endl;
}
}student1;
int main(){
}#include <iostream>
using namespace std;
struct checkup{
string name;
double height;
int weight;
double eyesight[2];
void BMI(){
cout << weight/(height^2) << endl;
}
};
int main(){
checkup student3={
.name="Phoebe",
.height=1.88,
.weight=70,
.eyesight[0] = 1.0;
.eyesight[1] = 1.2;
};
checkup student2={"Phoebe", 1.88, 70, 1.0, 1.2};
cin >> student1.name;
cout << "姓名" << student1.name << endl;
student2.BMI();
}
ps. 這邊.name 後面不用加()
()是函式才要加的
Grade student[3]={
{.name="aa", .height = 150,},
{.name="bb", .height = 160,},
{.name="cc", .height = 170,},
};struct identity{
int id;
string name;
};
struct checkup{
identity stu;
int height;
int weight;
int eyesight[2];
};typedef struct checkup{
string name;
int height;
int weight;
int eyesight[2],
void BMI{
cout << weight/(height^2) << endl;
}check;5
食物 1500 1
場地租金 2000 0
獎品 800 0
交通費 300 1
傳單 700 1
ans:
剩餘 7500
#include <iostream>
#include <string>
using namespace std;
// 定義支出項目結構
struct expenditure {
string item;
int amount;
bool pay;
}expend[100];// 創建支出項目陣列
int main() {
int income = 10000; // 收入
int numItems; //支出項目數量
cin >> numItems;
// 輸入支出項目資料
for (int i = 0; i < numItems; i++) {
cin >> expend[i].item >> expend[i].amount >> expend[i].pay;
}
// 計算總支出
int total = 0l;
for (int i = 0; i < numItems; i++) {
if (expend[i].pay) {
total += expend[i].amount;
}
}
// 輸出剩餘金額
cout << "剩餘 " << income - total << endl;
return 0;
}
一忠 陳芊邑
還記得之前聊過的終級密碼嗎?
不斷取中間值直到取到答案為止
65
1
100
紅色的線「不合法」,藍色的線「合法」
我們要找到藍色線的最左端
51
1
100
[51,100]
51
1
100
[51,74]
74
51
1
100
[62,74]
74
62
51
1
100
[62,67]
74
62
67
51
1
100
[64,67]
74
62
67
64
67
62
74
[65]
64
65
這樣就結束了嗎?
怎麼可能
接下來要講解範例
給你一個嚴格遞增的數列A1,A2,A3.....An,
&下面有幾個問題的詢問數k,
以及k個詢問的整數x,
求數列中是否存在一個Ai(1<=i<=n)的值與X相等?
#include <bits/stdc++.h>
using namespace std;
int bs(int arr[], int n, int ans) {
int left = 1;
int right = n;//數組長度
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == ans) {
return mid; // 返回找到的索引
} else if (arr[mid] < ans) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return 0; // 找不到則返回0
}
int main() {
int n, k;
cin >> n >> k;
int arr[n];
for (int i = 1; i <= n; ++i) {
cin >> arr[i];
}
for (int i = 0; i < k; ++i) {
int x;
cin >> x;
int ans = bs(arr, n, x);
cout << ans << endl;
}
return 0;
}
left = 左界
right = 右界
while (左比右小,代表邊界還正常) {
mid = 左右邊界的中間點
if (數列中間點的數值大於 ans) {
右半邊可以不用看,把右界移到中間(mid)
} else if (數列中間點的數值小於 ans) {
左半邊可以不用看,把左界移到中間(mid)
} else {
找到答案
}
}記得排序
確認區間定義、範圍
左右界如何改變
負數除法會有問題, 改用 left+(right-left)/2
看起來很簡單?很少?
對,我們還有一題範例
範例1說明:將第1位由2升至5需3^2金幣,第2位由4升至5需1^2金幣,全體最少有5級
輸入說明:
第1行有兩個正整數N或C,分別士兵數及金幣數
第2行有N個正整數a1~an
代表N個士兵目前的等級,皆以空白隔開
輸出說明:
請輸出一行正整數U,表示最少可全部升至U級(含)以上
#include <bits/stdc++.h>
using namespace std;
long long level[2000000],n;
long long x(long long lv){
//計算到等級lv所需要的錢
long long sum=0;
for(long long i=0;i<n;i++){
if(level[i]<lv){
//如果士兵等級<lv
sum=sum+(level[i]-lv)*(level[i]-lv);
//計算每個士兵的花費並加總
}
}
return sum;
//返回預算
}
int main(){
long long c;
long long l=1,r=2000000;
cin>>n>>c;
for(long long i=0;i<n;i++){
cin>>level[i];
}
while(l<=r){
//左閉右閉,使用等於搜索全部範圍
long long mid=l+(r-l)/2;
//預期的等級mid
if(x(mid)>c){
r=mid-1;
}
else{
l=mid+1;
}
}
cout<<r<<endl;//如果未找到精確值,輸出低於預算的最接近等級
}