# APCS 2023/10/22
## 前言
APCS好好玩 :D
當天整個爆忙,考完之後搞化學又搞辯論。
初筆:2023/10/22
末筆:2023/11/7
## 觀念題
第一節題目偏簡單,最難可能就bubble sort或逆序數對,沒什麼好說的。
第二節有BS、更難的bubble sort&逆序,噁心的雙遞迴、還有一堆我覺得只是在考計算的怪東西。
> 總之我覺得不好玩,然後88分是甚麼殘念鬼分數
## 實作題
### P1 [機械鼠](https://zerojudge.tw/ShowProblem?problemid=m370)
題意大概就是給你一個一維座標x,判剩下座標在x的左邊還右邊之後做一些小記錄。
> 水題無誤
:::spoiler code
```C++=
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 1.5e5;
main(){
ios_base::sync_with_stdio(false); cin.tie(0);
int n, x;
cin >> x >> n;
int lmn = 101, rmx = -101, lcnt = 0, rcnt = 0;
while (n--){
int a; cin >> a;
if (a < x){ //判max跟min不用在if裡面,但沒差啦
lcnt++; lmn = min(lmn, a);
}else{
rcnt++; rmx = max(rmx, a);
}
}
if (rcnt > lcnt){
cout << rcnt << " " << rmx << endl;
}else{
cout << lcnt << " " << lmn << endl;
}
}
```
:::
### P2 [卡牌遊戲](https://zerojudge.tw/ShowProblem?problemid=m371)
#### 題敘
跟之前的題目比算很好寫的二維陣列實作題,zj上的測資目前不夠強,只要做一次判斷就夠了。
> 仍然水,但我犯了一個蠢bug只拿60分,幸好有5級分,想看我的雲霄飛車體驗請往下走。
### P3 [搬家](https://zerojudge.tw/ShowProblem?problemid=m372)
#### 題敘
給n*m個形狀的水管(以不同字元表示),問依它的規則轉換後最大的連通塊大小
#### 解法
我是直接用dfs算連通塊,麻煩的是判定兩個水管是否連通,這裡使用布林陣列/bitset就可以快速計算啦(例如說{左, 上, 右, 下},1代表該方向能通,用(i + 2) % 4可以很快處理)。
> zj上要用bfs才能AC喔
#### 小趣事
我這題因為x座標的+1、-1寫反debug超久,但是心裡默念幾個學長姐、前輩的名字幾分鐘後就de出來了。(感謝李學姊、郭學長、黃老師、還有~~我忘記有沒有想到的~~黃學長可能有給我的加持)
> 上面那幾個人有一半不打競程,法力超強
> 2、3題因為code太麻煩又沒什麼營養就不打了
### P4 [投資遊戲](https://zerojudge.tw/ShowProblem?problemid=m373)
#### 題敘
算最大連續區間和,但最多可以忽略k個數的值。
#### 解法
令dp[i][j]代表考慮到第i個,用了j個金牌的答案
$O(nk)$ 的dp,轉移蠻直觀的。
```C++
dp[i][j] = max(dp[i - 1][j] + A[i], dp[i - 1][j - 1])
```
:::spoiler code
```C++
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 1.5e5;
ll A[MAXN + 10], dp[MAXN + 10][21];
main(){
ios_base::sync_with_stdio(false); cin.tie(0);
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> A[i];
for (int i = 0; i <= n; i++) for (int j = 0; j <= k; j++) dp[i][j] = -1e18;
dp[1][0] = A[1];
ll ans = max(dp[1][0], 0ll);
for (int i = 2; i <= n; i++) dp[i][0] = max(0ll, dp[i - 1][0]) + A[i], ans = max(dp[i][0], ans);
for (int j = 1; j <= k; j++){
for (int i = 1; i <= n; i++){
dp[i][j] = max(dp[i - 1][j] + A[i], dp[i - 1][j - 1]);
ans = max(dp[i][j], ans);
}
}
cout << ans << "\n";
}
```
:::
## 心得
先說成績,實作5😍😍😍😍❤️❤️❤️❤️
打競程的應該都知道APCS的題目並沒有多難,就算拿到5級分也不代表多強。但是其實APCS對我來說有蠻多特殊意義的,也才會有這篇怪怪心得文的出現。
我的程式之路說長不長,說短不短(從小學開始寫python的怪人)。不過我真正開始下定決心踏上這條道路的時候是在國三,而契機就是APCS。
我國三第一次去考APCS是滿懷期待、自信去的,結果被現實的4+3狠狠上了一課。從那時候才真正看到自己實力的不足,也看到了自己與電神們的差距。後來也許是因為不甘,抑或是對成為強者的追求,又或者是單純地想要好好享受比賽的過程,我決定讓競程進入生活,讓它成為我青春的一部分。
之後因緣際會下去上了[AA競程](https://aacpschool.com/)的課跟參加IONC(都超推),算是真正踏入了競程圈。光一個暑假,就學到了很多東西,AA的之後再細說吧。其實主要就是實力上的躍進與心態上的調整。如果當初沒有那場APCS,這一切都不會發生。
>幾個月是可以改變一個人很多的 by 學長
回到這次的檢定,P1、P2前20分鐘就處理掉了,沒什麼好說的。接下來P3看一下立刻想出解法就開始寫code,但是遇到了該死的bug,詳細可以看P3那邊的小趣事(HackMD才有)。這邊我在心態上的成長就顯現出來了,我毫不猶豫的去寫P4,剛好這次P4偏簡單,大概10幾分鐘就AC了,之後再調整好自己才回去debug P3並拿到AC。如果是之前的我,可能會糾結P3很久導致最後連P4都拿不到吧。
我覺得這次檢定算是對我進步的最大證明。例如在賽中一看到題目腦中立刻出現的解法,在看到的那刻就知道怎麼解的欣喜,讓我有 我的練習有價值 的感覺,實作的過程中也會想到一些自己過去吃的bug從而避開。而迅速想到第四題的轉移也代表~~我真的會通靈~~,我是指了解到dp的意義了。
還有終於可以快速冷靜下來debug,~~雖然可能跟學姊做法加持關聯比較大~~,即便可能之後還是會出現這種情況,可是不會像之前那樣往往過於短視近利,看到自己終於擺脫過去那種完全被情緒支配的感覺真的很好。
還有很多小東西也都令我蠻開心的,不過那些事就不足為外人道了。總之這些種種都讓我真真切切感受到,我進步了! 相信這就是當時的我想要得到的吧。
我還算不上是甚麼大電神。在別人眼中我的感動可能微不足道。這也不會是我的終點,可能連一個成就都稱不上(甚至我沒有特別準備這次檢定)。不過這次檢定是我對過去自己的一個交代,也象徵著我即將進行更高層次的追求。期待未來的我也能給現在的我一個完美的交代吧!
### 小去世
今天(11/7)9:00開放查成績,我在8:00的時候想到P2犯了致命的bug,整個人心情墜入谷底。毫不誇張的說,我那時候幾乎快哭出來了。但是後來我轉念一想,興許運氣好能過一些測資呢?然後我就開始拜天、拜地、拜學姊(X 最後成績出來拿了60分,加上其他三題拿滿共360,實作5級分!!!(那個,有在幫我做法的麻煩繼續,我很需要🤪🤪🤪
## 結語
之後(希望)有空再補code跟其他細節。
這次題目算蠻簡單了,我好幸運!