---
# System prepended metadata

title: 學習歷程-APCS解題筆記
tags: [競程, C++]

---

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