←返回文章列表
ITOUBLOGA

APCS 2025 10月 中級題解

考點:二維陣列模擬 (區域改值 & 邊界判斷)

第一題:彗星撞擊 (題目敘述)

  • 考點:二維陣列模擬 (區域改值 & 邊界判斷)
  • 題解
    • 主要是偵測以(a, b)為中心, 半徑為 s 上是否有恐龍, 如果沒有就每個點都扣掉 d
    • 創一個陣列紀錄每一個點上有幾隻恐龍
    • 遍歷影響範圍時,可以發現左界會是 b - s/2,上界是 a - s/2,因此可以左上角(a - s/2, b - s/2)去遍歷 s * s 的矩陣(記得要判斷邊界)
    • 如果有恐龍(dino[i][j] > 0) , 先將清醒的恐龍數量減去 dino[i][j] 然後將 dino[i][j] 的值改成 0 ,否則全部減 d
#include<bits/stdc++.h>
using namespace std;
 
int main(){
    int R=0,C=0,D=0,K=0,M=0;
    cin >> R >> C >> D;
    vector<vector<int>>mp (R,vector<int>(C,D));
    vector<vector<int>>aw (R,vector<int>(C));
    cin >> K;
    for(int i=0;i<K;i++){
        int a=0,b=0;
        cin >> a >> b;
        aw[a][b]++;
    }
    cin >> M;
    for(int i=0;i<M;i++){
        int a=0,b=0,s=0,d=0;
        cin >> a >> b >> s >> d;
        int r1 = max(0, a - s/2);
        int r2 = min(R-1, a + s/2);
        int c1 = max(0, b - s/2);
        int c2 = min(C-1, b + s/2);
        bool hasDino = false;
        for(int x=r1;x<=r2;x++){
            for(int y=c1;y<=c2;y++){
                if(aw[x][y] != 0) hasDino = true;
            }
        }
        if(hasDino){
            for(int x = r1; x <= r2; x++)
                for(int y = c1; y <= c2; y++)
                    aw[x][y] = 0;
        }else{
            for(int x = r1; x <= r2; x++)
                for(int y = c1; y <= c2; y++)
                    mp[x][y] -= d;
        }
    }
    
    int maxVal = mp[0][0];
    int minVal = mp[0][0];
 
    for(int i = 0; i < R; i++){
        for(int j = 0; j < C; j++){
            maxVal = max(maxVal, mp[i][j]);
            minVal = min(minVal, mp[i][j]);
        }
    }
    
    int total = 0;
    for(int i = 0; i < R; i++){
        for(int j = 0; j < C; j++){
            total += aw[i][j];
        }
    }
    cout << maxVal << " " << minVal << " " << total;
}

第二題:航空拍照圖 (題目敘述)

  • 考點:二維陣列模擬 (陣列旋轉)
  • 題解
    • 如果 r = c,翻轉的邊長都一樣,4個方向都要轉,反之 r != c,只要轉 0 度和 180 度,因為其他兩個轉出來的邊常會和原本的不符合
    • 只要會翻轉陣列理論上這題就能寫出來 (另b為原本陣列)
      • 向右翻轉 0 度, 即為 b 陣列
      • 向右翻轉 90 度,arr[j][r-i-1] = b[i][j]
      • (剩下的我用做幾次翻轉 90 度去跑)
#include <bits/stdc++.h>
using namespace std;
 
vector<vector<int>> rotate90(vector<vector<int>> mp){
    int R = mp.size();
    int C = mp[0].size();
 
    vector<vector<int>> res(C, vector<int>(R));
 
    for(int i = 0; i < R; i++){
        for(int j = 0; j < C; j++){
            res[j][R - 1 - i] = mp[i][j];
        }
    }
    return res;
}
 
int compare(vector<vector<int>>& A, vector<vector<int>>& B){
    int R = A.size();
    int C = A[0].size();
 
    int cnt = 0;
 
    for(int i=0;i<R;i++){
        for(int j=0;j<C;j++){
            if(A[i][j] == B[i][j]) cnt++;
        }
    }
 
    return cnt;
}
 
int main(){
    int R, C;
    cin >> R >> C;
 
    vector<vector<int>> A(R, vector<int>(C));
    vector<vector<int>> B(R, vector<int>(C));
 
    for(int i=0;i<R;i++)
        for(int j=0;j<C;j++)
            cin >> A[i][j];
 
    for(int i=0;i<R;i++)
        for(int j=0;j<C;j++)
            cin >> B[i][j];
 
    int total = R * C;
    int best = 0;
 
    for(int i=0;i<4;i++){
 
        if(B.size() == A.size() && B[0].size() == A[0].size()){
            best = max(best, compare(A, B));
        }
 
        B = rotate90(B);
    }
 
    cout << (best * 100 / total) << "%\n";
}

第三題:商品包裝地 (題目敘述)

  • 考點:字串
  • 題解
    • 題目簡單來說就是判斷奇數位置的數字總和 + 3 * 奇數位置的數字總和是否為 10 的倍數
    • 不需要去特判驗證碼 c ,因為他剛好在奇數位置,直接加進去就好
    • 如果該條碼合法要將其儲存 & 統計前三碼出現次數,以下有兩種方法
      • 抓前三碼用整數 int a = (s[0] - '0'), b = (s[1] - '0'), c = (s[2] - '0'),該數字是 a * 100 + b * 10 + c,將其存在 cnt 陣列,最後輸出要記得補 0 (Example 1)
      • 直接以前三碼為 index ,會使用到 map <string, int> mp
#include <bits/stdc++.h>
using namespace std;
 
int main(){
    int n;
    cin >> n;
    string key;
    map<string,int> cnt;
    for(int i=0;i<n;i++){
        int so=0,se=0;
        cin >> key;
        for(int j=0;j<12;j++){
            int v = key[j] - '0';
 
            if(j % 2 == 0) so += v;
            else se += v;
        }
        int x = (so + 3 * se) % 10;
        int check = key[12] - '0';
 
        if( (x + check) % 10 == 0 ){
            cnt[key.substr(0,3)]++;
        }
    }
    string ans;
    int mx = 0;
 
    for(auto &p : cnt){
        if(p.second > mx){
            mx = p.second;
            ans = p.first;
        }
    }
 
    cout << ans << " " << mx << "\n";
}
GUESTBOOK