2021.7.10 校內模擬賽遊記
嚴重事故徵候 over and over again
這次 事故徵候 模擬賽,暴露出我 安全意識淡薄,形式主義突出 省略標準程式的老問題。
T2 掛成 \(0\) 分了。
A
給定序列 \(a\), 問能否通過 \(a_i \to a_{i-1} + a_{i+1} - a_i\) 的操作變成 \(b\)。
看到 A 題嚇死了,開始想了 30min+ 沒有思路,先跳過了。
然後寫完 T2, 看過 3、4 後又來想,恍然大悟了。
首先如果把三個數都減去 \(x\), 那麼最後結果減少了倆加上了一個,所以結果也被減去了 \(x\),並不會對數的相對大小造成什麼影響,那麼就簡化問題,吧 \(x, y, z\)
眾所周知,排列兩兩交換能達到任何排列,而換不出其它數來,所以只要比較差的多重集是否相同就可以了。
B
這就是出事的題。
構造排列滿足輸入的相鄰兩數的大小關係,同時讓 LIS 儘可能 大/小
很快就想到了一個可行的構造,雖然有點複雜,但至少是對的,寫完調了一會兒就放著了。
所謂的檢查單完全只是掃了兩眼程式碼,測試部分也只檢查了是否是一個排列,而沒有檢查相對大小的關係,然後就成功掛分了。
可笑的是,程式碼的末尾還寫著
// 0137Z - CCP // 0142Z - CKC
其實連檢查單都沒有默出來就打上了 CKC 的標記。
今後必須要嚴格執行檢查單,並且強制要求在程式碼末尾默寫檢查單且兩個標記不得使用縮寫,強制要求寫完全稱。
C
有箱子的網格圖裡從左上到右下,可以推箱子但不能推出去,求路徑數。
想到了 dp 要一塊轉移,可是恍然發現這樣會有重複。
然後就以為這是個錯誤的思路,直接棄掉,想了會兒容斥未果就寫了個暴力交了。
有重複就想辦法解決啊!!!
其實只要強制規定當前格轉向,然後一塊的轉移用字首和優化就可以了。
程式碼裡保留了原來的程式碼。
void TYT() { for (int i = 1; i <= n; i++) std::cin >> (map[i] + 1); for (int i = n; i >= 1; i--) for (int j = m; j >= 1; j--) r[i][j] = r[i][j+1] + (map[i][j] == 'R'), d[i][j] = d[i+1][j] + (map[i][j] == 'R'); f[n][m][0] = f[n][m][1] = sum[n][m][0] = sum[n][m][1] = 1; for (int i = n; i >= 1; i--) for (int j = m; j >= 1; j--) { if (i == n && j == m) continue; f[i][j][0] = (sum[i][j+1][1] - sum[i][m-r[i][j+1]+1][1] + P) % P; f[i][j][1] = (sum[i+1][j][0] - sum[n-d[i+1][j]+1][j][0] + P) % P; sum[i][j][0] = (sum[i+1][j][0] + f[i][j][0]) % P; sum[i][j][1] = (sum[i][j+1][1] + f[i][j][1]) % P; } std::cout << (f[1][1][1] + f[1][1][0]) % P; }
D
我居然沒有想到那麼顯然的鏈上部分分的倍增?!
想了半天未果,連暴力都沒有想出來。成功 \(0\) 分。
題解在這裡寫了,不重複發了。