# 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`