東京海上日動 プログラミングコンテスト2020
コンテスト前のレート:1778
レート通りのパフォーマンスが得られる順位:684位
A - Nickname
問題
ABC-Aと同レベルだと思う。
思考過程
- substringで連続した部分文字列を取得できる。
- 最初の3文字にするか最後の3文字にするか一瞬考えて最初の3文字にした。
import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); String s = sc.next(); sc.close(); System.out.println(s.substring(0, 3)); } }
ここまで0分46秒+0ペナ。552位。
B - Tag
問題
平均的なABC-Bより凡ミスが怖い見た目をしている気はするけど、それにしてもちょっと時間かけ過ぎた。
思考過程
- は近付く方向に、は遠ざかる方向に動き続けるのが最適。つまり秒あたりだけ距離が縮まっていく。
- とりあえずならば距離が縮まないので 'NO'。
- 秒間に縮まる距離が最初の間の距離以上なら 'YES'。
- を個掛け算するのでオーバーフローに注意。
import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); int a = sc.nextInt(); int v = sc.nextInt(); int b = sc.nextInt(); int w = sc.nextInt(); int t = sc.nextInt(); sc.close(); // この判定はいらなかった if (w >= v) { System.out.println("NO"); return; } int d = Math.abs(a - b); if ((long) (v - w) * t >= d) { System.out.println("YES"); } else { System.out.println("NO"); } } }
ここまで4分58秒+0ペナ。911位。
C - Lamps
問題
こういう問題の計算量見積もりができない。
思考過程
- とりあえず愚直にやった場合を考えると、以下の通りでくらい。
- 各電球が照らしている範囲にするのが回。最大。
- 上記の処理を回。ここまでが回分。
- 上記の処理をさらに回。
- 回の部分は、いもす法を使えばとなるが、これでも。
- 数値を適当に変えてみて推移を眺めてみたりするが、特にエスパーできそうな法則は見えてこない。
- が十分に大きければ、最終的には全部になる。
- 推移をもう一度眺めると、各電球の光の強さは、平均的には毎回よりはたくさん増えそう? つまり、全部になるまで最悪でもまではかからない?
- 他に計算量落とせる方法も思いつかないので、とりあえずそれに賭けてみる。 →AC
import java.io.BufferedReader; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] sa = br.readLine().split(" "); int n = Integer.parseInt(sa[0]); int k = Integer.parseInt(sa[1]); sa = br.readLine().split(" "); int[] a = new int[n + 1]; for (int i = 0; i < n; i++) { a[i] = Integer.parseInt(sa[i]); } br.close(); for (int i = 0; i < k; i++) { // 1回分の操作をいもす法で行う int[] b = new int[n + 1]; for (int j = 0; j < n; j++) { int l = Math.max(j - a[j], 0); int r = Math.min(j + a[j] + 1, n); b[l]++; b[r]--; } for (int j = 1; j < b.length; j++) { b[j] += b[j - 1]; } a = b; // 全部Nなら終了 boolean all = true; for (int j = 0; j < n; j++) { if (a[j] < n) { all = false; break; } } if (all) { break; } } StringBuilder sb = new StringBuilder(); for (int i = 0; i < n; i++) { sb.append(a[i]).append(' '); } sb.deleteCharAt(sb.length() - 1); System.out.println(sb.toString()); } }
ここまで28分17秒+0ペナ。402位。
D - Knapsack Queries on a tree
問題
30分ほど考えて解けず。
思考過程
- クエリ回分を普通にナップサックで解こうとすると、それだけでくらい。
- 全部事前計算しておくとすると、はよりも悪くて余計に駄目。時間だけでなくメモリも。
- クエリを処理する順番を都合よく入れ替えたりしたところで、全部葉付近とかだったら意味はなさそうな気がする。
ナップサックではなく全探索する方向性を全く考えられなかったのが敗因かな・・・。
E - O(rand)
問題
1時間ほど考えて解けず。
結構いいところまで考えた気がしたけど、気がしただけで駄目な方向に向かっていたっぽい。
思考過程
- つのビットについて見たときのの組合せ通りを考える。
- の場合、しか選べない。
- の場合、とをそれぞれ個以上選ぶ。
- の場合、条件は満たせず、通り。
- の場合、しか選べない。
- については、個の内が個とすると、通りとなりそう。も同様。
- については、全体の通りから、余事象となるとの分を引けば求められそう。
- ここまでをビットごとに求めて掛け合わせれば解けるのでは?と思ったが、そもそもビットごとに独立ではない。
- 値の内、ビット目がになるものの集合をと表すと、「の全集合から個以上ずつ選択されているような選択方法は何通りか」という問題になる気がするが、各値は複数(半分)の集合に含まれていてややこしく、解ける気がしない。
一応包除原理という単語だけは頭をよぎったりはしたのだが、まともに使えるレベルに達していないので、適用の仕方もまともに考えられるわけがなかった。
青半ばになってもまだ応用力以前に武器が揃っていない気がして仕方がない。
F問題は一応問題文を読んだだけ。
最終結果:ABCの3完、28分17秒、546位、パフォーマンス1898
レート変動:1778→1791
今回は良い正解者数傾斜だと思うけど、個人的にはARC級のB問題は茶diffあるかないかくらいには難しくしてほしいと思う。BとCの崖が大きくなりがちなので。