--- title: "學習歷程-APCS解題筆記" date: 2025-02-02 tags: [程式, 學習] --- # 學習歷程-APCS解題筆記 ## 2016年03月 1. 成績指標 https://zerojudge.tw/ShowProblem?problemid=b964 **解題思路:** 1. 輸入分數 2. 用sort排列 3. 用迴圈判斷最大不及格值和最小及格值 4. 輸出答案 **遇到的困境:** 1. 不知如何儲存最小即格和最大不及格,最後用他們和"及格分數60的差"去比大小來更新最大最小值 2. 在測試是測資時發現,忘了把加減60後的值還原成原本的分數 **程式碼:** ```cpp= #include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); int n,high=41,low=61; cin>>n; int a[n]; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<'\n'; for(int i=0;i<n;i++){ if(a[i]<60){ low=min(low,60-a[i]); } else{ high=min(high,a[i]-60); } } if(low==61) cout<<"best case"<<'\n'; else cout<<60-low<<'\n'; if(high==41) cout<<"worst case"<<'\n'; else cout<<high+60<<'\n'; } ``` ## 2016年10月 1. 三角形辨別 https://zerojudge.tw/ShowProblem?problemid=c294 **解題思路:** 1. 因為要用sort,所以用陣列去儲存三角形的邊 2. 用sort做完排序並輸出 3. 先判斷是否為三角形,在判斷是甚麼種類的三角形,並輸出 **遇到的困境:** 1. 原本要用三個變數儲存邊長,但是發現要排序所以只能用陣列 2. 一開始忘記先判斷是否為三角形,再判斷種類,造成測試時錯誤 **程式碼:** ```cpp= #include <bits/stdc++.h> #define int unsigned long long using namespace std; signed main() { int a[3],A,B,C; cin>>a[0]>>a[1]>>a[2]; sort(a,a+3); cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<'\n'; A=a[0]*a[0]; B=a[1]*a[1]; C=a[2]*a[2]; if(a[0]+a[1]>a[2]){ if(A+B==C) cout<<"Right"<<'\n'; else if(A+B>C) cout<<"Acute"<<'\n'; else if(A+B<C) cout<<"Obtuse"<<'\n'; } else cout<<"No"<<'\n'; } ``` ## 2017年03月 1. 秘密差 https://zerojudge.tw/ShowProblem?problemid=c290 **解題思路:** 1. 用字串的方式儲存數字,因為數字最多有1000位數 2. 一一把每一位切出來,並存在A,B 3. 用比大小的方式去用"A和B的最大值-A和B的最小值"得到絕對值的功用,因為系統版本不支援"abs(a,b)" 4. 輸出答案 **遇到的困境:** 1. 一開始我用可以存最大正數的"unsigned long long",但還是不足1000位數,所以我就想到用字串的方式去儲存 2. 因為Zero-Judge的編譯器C++ 14不支援abs(a,b),所以只能用"max(a,b)-min(a,b)" **程式碼:** ```cpp= #include<bits/stdc++.h> #define int unsigned long long using namespace std; signed main(){ ios::sync_with_stdio(0); int A = 0, B = 0; string s; cin >> s; for (int i=0; i<s.size(); i++){ if (i % 2){ B+= s[i]-'0'; } else { A+= s[i]-'0'; } } cout<<max(A,B)-min(A,B)<<'\n'; } ``` ## 2017年10月 1. 邏輯運算子 https://zerojudge.tw/ShowProblem?problemid=c461 **解題思路:** 1. 直接用三個變數儲存數字 2. 在判斷是否符合AND,OR,XOR 3. 輸出答案 **遇到的困境:** 1. 因為剛好在練習使用void,在過程中,我忘了呼叫,所以還要多加熟悉 2. 因為xor不等價於!or,所以只能自己判斷 **程式碼:** ```cpp= #include <bits/stdc++.h> #define int long long using namespace std; void solve(int x,int y,int z) { int p; if((x==0&&y!=0)||(x!=0&&y==0)) p=1; else p=0; int s=x and y,o=x or y; if(s==z ||o==z || p==z) { if(s==z) cout<<"AND"<<'\n'; if(o==z) cout<<"OR"<<'\n'; if(p==z) cout<<"XOR"<<'\n'; } else cout<<"IMPOSSIBLE"<<'\n'; } signed main() { int a,b,c; cin>>a>>b>>c; solve(a,b,c); } ``` ## 2020年10月 1. 人力分配 https://zerojudge.tw/ShowProblem?problemid=f312 **解題思路:** 1. 用多個變數儲存二元方程式的係數和人數 2. 直接用迴圈去跑收益,再用max()去取最大值 3. 輸出最大收益 **遇到的困境:** 1. 再用max()去取最大值時,收益初始值一開始我先設為"0",但是執行時NA,因為我沒考慮到收益也會負的,所以最後我把它設成long long的最小值 2. 再用max()時,少用括號造成邏輯錯誤,要時時提醒自己括號不能省 **程式碼:** ```cpp= #include <bits/stdc++.h> #define int long long using namespace std; signed main() { ios::sync_with_stdio(0); cin.tie(0); int A,B,C,a,b,c,n,y=-LONG_LONG_MAX,p; cin>>A>>B>>C>>a>>b>>c>>n; for(int i=0;i<=n;i++){ p=n-i; y=max(y,((A*p*p+B*p+C)+(a*i*i+b*i+c))); } cout<<y<<'\n'; } ``` ## 2021年09月 1. 七言對聯 https://zerojudge.tw/ShowProblem?problemid=g275 **解題思路:** 1. 輸入對聯 2. 分別判斷三個條件並用布林值儲存 3. 綜合以上判斷是否符規則 4. 輸出A,B,C或是nope **遇到的困境:** 1. 要用三維陣列,對不太熟悉陣列的我是一大難題 2. 條件判斷,就是一一把條件轉為程式碼,但是當我判斷完時卻不知道要如何儲存"ture"和"false",所以又多開一個布林值,方便最後判斷 3. 在測試測資時,我發現答案竟然全錯,我想了很久終於想到:在陣列中元素是從"0"開始,所以一句的最後一個字不是索引值"7",而是"6" **程式碼:** ```cpp= #include <bits/stdc++.h> #define int long long using namespace std; signed main() { ios::sync_with_stdio(0); cin.tie(0); int n; cin>>n; int a[n][2][7]; bool A[2],B=false,C=false; A[0]=false; A[1]=false; for(int i=0;i<n;i++){ for(int j=0;j<2;j++){ for(int k=0;k<7;k++){ cin>>a[i][j][k]; } } } for(int i=0;i<n;i++){ for(int g=0;g<2;g++){ if(a[i][g][1]!=a[i][g][3] && a[i][g][1]==a[i][g][5]) A[g]=true; } if(a[i][0][6]==1 && a[i][1][6]==0) B=true; if(a[i][0][1]!=a[i][1][1] && a[i][0][3]!=a[i][1][3] && a[i][0][5]!=a[i][1][5]) C=true; if(A[0]==false || A[1]==false) cout<<"A"; if(B==false) cout<<"B"; if(C==false) cout<<"C"; if(A[0]==true &&A[1]==true&&B==true&&C==true) cout<<"None"; cout<<'\n'; A[0]=false; A[1]=false; B=false; C=false; } } ``` ## 2021年11月 1. 修補圍籬 https://zerojudge.tw/ShowProblem?problemid=g595 **解題思路:** 1. 先以陣列儲存圍籬長度 2. 用迴圈邊修補圍籬邊更新修補所需的成本 3. 輸出最後更新完的成本 **遇到的困境:** 1. 在判斷是否為頭尾時,因為``` if ```忘了加```else```所以造成成本的質一直亂迴圈,所以debug很久 **程式碼:** ```cpp= #include <bits/stdc++.h> #define int long long using namespace std; signed main() { ios::sync_with_stdio(0); cin.tie(0); int n,mon=0; cin>>n; int a[n]; for(int i=0;i<n;i++) cin>>a[i]; for(int i=0;i<n;i++){ if(a[i]==0){ if(i==0) { a[i]=a[i+1]; mon+=a[i]; } else if(i==n-1) { a[i]=a[i-1]; mon+=a[i]; } else { a[i]=min(a[i+1],a[i-1]); mon+=a[i]; } } } cout<<mon<<'\n'; } ``` ## 2022年06月 1. 數字遊戲 https://zerojudge.tw/ShowProblem?problemid=i399 **解題思路:** 1. 先以三個變數儲存數字 2. 分出是三同、兩同、全不同 3. 輸出最多相同個數和排大小輸出 **遇到的困境:** 1. 在判斷相同個數時要先判斷三同,再來在判斷全部都不同,剩下的就是兩同,因為在排序後,兩同會有兩種可能 2. 在用```if```時忘了把算數運算子轉成關係運算子 **程式碼:** ```cpp= #include <bits/stdc++.h> #define int long long using namespace std; signed main() { ios::sync_with_stdio(0); cin.tie(0); int a,b,c,n[3]; cin>>a>>b>>c; n[0]=a; n[1]=b; n[2]=c; sort(n,n+3); if(a==b&&b==c&&a==c){ cout<<"3 "<<a<<'\n'; } else if(a!=b&&b!=c&&a!=c){ cout<<"1 "<<n[2]<<" "<<n[1]<<" "<<n[0]; } else{ cout<<"2 "; if(n[2]==n[1]) cout<<n[2]<<" "<<n[0]<<'\n'; else cout<<n[2]<<" "<<n[0]<<'\n'; } } ```