---
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';
}
}
```