---
# System prepended metadata

title: APCS 2022 10月 實作題
tags: [APCS]

---

# APCS 2022 10月 實作題



## 第一題 巴士站牌
#### 題目: [https://zerojudge.tw/ShowProblem?problemid=i428](https://zerojudge.tw/ShowProblem?problemid=i428)

#### 解題關鍵: 迴圈、abs()


#### 程式碼
```cpp=
#include<bits/stdc++.h>
using namespace std;

int n, Min = 999999, Max = -1;
vector<pair<int, int> > road;

int main(){
    //輸入
    cin>>n;
    road.resize(n);
    for(int i=0; i<n; i++){
        int x, y;
        cin>>x>>y;
        road[i] = {x, y};
    }
    
    for(int i=1; i<n; i++){
        int l = abs(road[i].first - road[i-1].first) + abs(road[i].second - road[i-1].second);
        Min = min(Min, l);
        Max = max(Max, l);
    }
    cout<<Max<<' '<<Min<<'\n';
}
```


## 第二題
#### 題目: [https://zerojudge.tw/ShowProblem?problemid=j123](https://zerojudge.tw/ShowProblem?problemid=j123)

#### 題解: 待補
#### 程式碼
```cpp=
```


## 第三題 石窟探險
##### 題目: [https://zerojudge.tw/ShowProblem?problemid=j124](https://zerojudge.tw/ShowProblem?problemid=j124)

#### 題解關鍵: *奇數 -> 3個子節點, 偶數 -> 2個子節點* 、遞迴


#### 程式碼
```cpp=
#include<bits/stdc++.h>
using namespace std;

int inx = 0;
string str;
vector<int> node;
long long sum;

void build(int n){  // n = 父節點
  if(n%2==0){
    for(int i=1; i<=2; i++){
      int nm = node[inx];
      inx++;
      if(nm == 0) continue;
      sum += abs(n - nm);
      build(nm);
    }
  }else{
    for(int i=1; i<=3; i++){
      int nm = node[inx];
      inx++;
      if(nm == 0) continue;
      sum += abs(n - nm);
      build(nm);
    }
  }
}

int main(){
  ios::sync_with_stdio(0), cin.tie(0);
  getline(cin, str);
  stringstream ss;
  ss<<str;
  while(ss>>str){
    node.push_back(stoi(str));
  }
  inx = 1;
  build(node[0]);
  cout<<sum<<'\n';
}

```

## 第四題 蓋步道
#### 題目: [https://zerojudge.tw/ShowProblem?problemid=j125](https://zerojudge.tw/ShowProblem?problemid=j125)

#### 題解1: BFS + 二分搜
使用二分搜嘗試每種高度h，再用BFS找嘗試h是否可行。

#### 程式碼
```cpp=
#include<bits/stdc++.h>
using namespace std;

int n, ans; // n:長與寬
int g[305][305]; //圖
int dx[4] = {0, 0, 1, -1}; //x方向 
int dy[4] = {1, -1, 0, 0}; //y方向

// 走訪
bool bfs(int h){
    queue<vector<int>> qu;
    qu.push({1, 1, 0});
    bool vis[305][305] = {0};
    
    while(!qu.empty()){
        int x = qu.front()[0], y = qu.front()[1], dis = qu.front()[2];
        qu.pop();
        vis[x][y] = true;
        
        if(x == n && y == n){
            ans = dis;
            return true;
        }
        for(int i=0; i<4; i++){
            int nx = x+dx[i], ny = y+dy[i];
            if(1<=nx && nx<=n && 1<=ny && ny<=n && vis[nx][ny] == false){
                if(abs(g[x][y] - g[nx][ny]) <= h){
                    vis[nx][ny] = true;
                    qu.push({nx, ny, dis+1});
                } 
            }
        }
    }
    return false;
}

int main(){
    ios::sync_with_stdio(0), cin.tie(0);
    //輸入
    cin>>n;
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            cin>>g[i][j];
        }
    }
    
    //r值是最小高度
    int l = -1, r = 1e6;
	
    // 二分搜
    while(r-l > 1){
        int mid = (r+l)/2;
        if(bfs(mid)){
            r = mid;
        }
        else{
            l = mid;
        }
    }

    cout<<r<<'\n'<<ans<<'\n';
    return 0;
}
```

###### tags: `APCS`

