# APCS 2022/10 題解 ## ==巴士站牌== ### <font color="0E81A6">敘述</font> [巴士站牌](https://zerojudge.tw/ShowProblem?problemid=i428) ### <font color="0E81A6">核心</font> 條件判斷 ### <font color="0E81A6">思路</font> 不用陣列。 ```c++= #include<bits/stdc++.h> using namespace std; int main() { int n; int x1,x2,y1,y2; int Max=-1,Min=1000; int distance; scanf("%d%d%d",&n,&x1,&y1); for(int i=1;i<n;i++) { scanf("%d%d",&x2,&y2); distance=abs(x2-x1)+abs(y2-y1); Max=max(Max,distance); Min=min(Min,distance); x1=x2,y1=y2; } printf("%d %d",Max,Min); } ``` ## ==運貨站== ### <font color="0E81A6">敘述</font> [運貨站](https://zerojudge.tw/ShowProblem?problemid=j123) ### <font color="0E81A6">核心</font> 模擬、二維陣列 ### <font color="0E81A6">思路</font> 直接模擬就好。 ```c++= #include <bits/stdc++.h> using namespace std; int r, c; bool taken[40][60]; int used; int no; void A(int j) { int i = c; for(;i >= 0;i--) { if(i == 0 || taken[j][i-1] || taken[j+1][i-1] || taken[j+2][i-1] || taken[j+3][i-1]) break; } if(i >= c) no++; else { taken[j][i] = true; taken[j+1][i] = true; taken[j+2][i] = true; taken[j+3][i] = true; used += 4; } } void B(int j) { int i = c+2; for(;i >= 2;i--) { if(i == 2 || taken[j][i-3]) break; } if(i >= c) no++; else { taken[j][i] = true; taken[j][i-1] = true; taken[j][i-2] = true; used += 3; } } void C(int j) { int i = c+1; for(;i >= 1;i--) { if(i == 1 || taken[j][i-2] || taken[j+1][i-2]) break; } if(i >= c) no++; else { taken[j][i] = true; taken[j+1][i] = true; taken[j][i-1] = true; taken[j+1][i-1] = true; used += 4; } } void D(int j) { int i = c+2; for(;i >= 2;i--) { if(i == 2 || taken[j+1][i-3] || taken[j][i-1]) break; } if(i >= c) no++; else { taken[j+1][i] = true; taken[j+1][i-1] = true; taken[j+1][i-2] = true; taken[j][i] = true; used += 4; } } void E(int j) { int i = c+1; for(;i >= 1;i--) { if(i == 1 || taken[j][i-1] ||taken[j+1][i-2] || taken[j+2][i-2]) break; } if(i >= c) no++; else { taken[j][i] = true; taken[j+1][i] = true; taken[j+2][i] = true; taken[j+1][i-1] = true; taken[j+2][i-1] = true; used += 5; } } int main(){ int q; cin >> r >> c >> q; while(q--){ char ch; int j; cin >> ch >> j; if(ch == 'A') A(j); if(ch == 'B') B(j); if(ch == 'C') C(j); if(ch == 'D') D(j); if(ch == 'E') E(j); } cout << r * c - used << ' ' << no << '\n'; } ``` ## ==石窟探險== ### <font color="0E81A6">敘述</font> [石窟探險](https://zerojudge.tw/ShowProblem?problemid=j124) ### <font color="0E81A6">核心</font> DFS、Tree ### <font color="0E81A6">思路</font> DFS就完事。 ```c++= #include <bits/stdc++.h> using namespace std; long long sum = 0; void dfs(int last) { int n; cin >> n; if (!n) return; if (last) sum += abs(n-last); if (n & 1) { dfs(n); dfs(n); dfs(n); } else { dfs(n); dfs(n); } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); dfs(0); cout << sum; } ``` ## ==蓋步道== ### <font color="0E81A6">敘述</font> [蓋步道](https://zerojudge.tw/ShowProblem?problemid=j125) ### <font color="0E81A6">核心</font> DFS、BFS、二分搜 ### <font color="0E81A6">思路</font> 先二分搜最大高度差的最小值(可到達右下),用DFS去做。 接著以此高度BFS就是答案。 ```c++= #include<bits/stdc++.h> using namespace std; #define piii pair<pair<int,int>,int> #define ff first.first #define fs first.second #define pii pair<int,int> int n; int height[300][300]; bool visit[300][300]; int di[4]={1,0,-1,0},dj[4]={0,1,0,-1}; int bfs(int hDiff) { memset(visit,false,sizeof(visit)); queue<piii> Q; Q.push({{0,0},0}); pii target={n-1,n-1}; while(!Q.empty()) { int x=Q.front().ff,y=Q.front().fs; int route=Q.front().second; if(make_pair(x,y)==target) return route; Q.pop(); for(int dir=0;dir<4;dir++) { int i=x+di[dir],j=y+dj[dir]; if(i>=0&&i<n&&j>=0&&j<n&&!visit[i][j]&&abs(height[i][j]-height[x][y])<=hDiff) { Q.push({{i,j},route+1}); visit[i][j]=true; } } } } bool dfs(int hDiff) { memset(visit,false,sizeof(visit)); vector<pii> stk; stk.push_back({0,0}); while(!stk.empty()) { int x=stk.back().first,y=stk.back().second; stk.pop_back(); if(x==n-1&&y==n-1) return true; for(int dir=0;dir<4;dir++) { int i=x+di[dir],j=y+dj[dir]; if(i>=0&&i<n&&j>=0&&j<n&&!visit[i][j]) { int h=abs(height[i][j]-height[x][y]); if(h<=hDiff) { stk.push_back({i,j}); visit[i][j]=true; } } } } return false; } int findh() { int l=0,r=1e6,mid; while(l<r) { mid=(l+r)/2; bool can=dfs(mid); if(can) r=mid; else l=mid+1; } return l; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) scanf("%d",&height[i][j]); } int maxhDiff=findh(); printf("%d\n%d\n",maxhDiff,bfs(maxhDiff)); } ```