モノグサプログラミングコンテスト2022(AtCoder Beginner Contest 238)(Rated範囲外)
コンテスト前のレート:2074
(Ratedだとしたら)レート通りのパフォーマンスが得られる順位:306位(2000点、95分33秒)
A - Exponential or Quadratic
思考過程
- が十分大きければだが、小さい時は微妙なので、の時の値を全部書き出してみる。
- 以下より、との場合条件を満たすことがわかる。
2^n n^2 n=1 2 1 n=2 4 4 n=3 8 9 n=4 16 16 n=5 32 25 n=6 64 36
import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); sc.close(); if (n == 1 || n >= 5) { System.out.println("Yes"); } else { System.out.println("No"); } } }
ここまで2分14秒+0ペナ。1032位。
B - Pizza
思考過程
- 少し見方を変えれば、長さの円環に距離ごとに切れ込みを入れる操作を行っているとみなすことができる。
- 切れ込みが入っているかどうかを長さのboolean型配列で持ってもよいが、切れ込みの位置の集合を持っておいた方が、位置の差を計算しやすそう。
import java.util.Scanner; import java.util.TreeSet; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = sc.nextInt(); } sc.close(); TreeSet<Integer> set = new TreeSet<>(); int x = 0; set.add(0); set.add(360); for (int i = 0; i < n; i++) { x += a[i]; x %= 360; set.add(x); } Integer[] arr = set.toArray(new Integer[0]); int ans = 0; for (int i = 1; i < arr.length; i++) { ans = Math.max(ans, arr[i] - arr[i - 1]); } System.out.println(ans); } }
ここまで6分32秒+0ペナ。369位。
C - digitnum
思考過程
- 桁の数は個、桁の数は個、のように桁増えるごとに個数は倍になっていく。
- からを引いて答えに~の和を加算する。
からを引いて答えに~の和を加算する。
のような繰り返し処理ができる。 - ただし、回目の操作でを下回った場合は~の和を求めて終了する。
import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); long n = sc.nextLong(); sc.close(); int mod = 998244353; long a = 9; long ans = 0; while (n > 0) { if (n <= a) { ans += n % mod * (n % mod + 1) / 2; ans %= mod; break; } ans += a % mod * (a % mod + 1) / 2; ans %= mod; n -= a; a *= 10; } System.out.println(ans); } }
ここまで15分00秒+0ペナ。280位。
D - AND and SUM
思考過程
- は、を進数で表した時にとなる桁は共にであり、となる桁は両方か片方のみである必要がある。
- その高々一方がとなる部分を単一の数で表すとすると、、より、となり、となる。
- とでとなる桁が重複していなければ"Yes"。
- 数のである桁が重複していないかは、ANDを取ってかどうかで判定できる。
import java.io.PrintWriter; import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); int t = sc.nextInt(); PrintWriter pw = new PrintWriter(System.out); for (int z = 0; z < t; z++) { long a = sc.nextLong(); long s = sc.nextLong(); long b = a * 2; long c = s - b; if (c >= 0 && (a & c) == 0) { pw.println("Yes"); } else { pw.println("No"); } } pw.flush(); sc.close(); } }
ここまで21分05秒+0ペナ。206位。
E - Range Sums
思考過程
- なんとなくUnionFindっぽさを感じて仕方がない。
- ただし例3のようにたったつの情報で"Yes"となることもあり得るので、全体が連結になる必要があるわけではない。
- ~の個の点を持ち、ではとを連結することにし、最終的にとが同一連結成分になっていれば"Yes"となりそう。
- 例えば間と間の値がわかれば、間の値も求められるようになることから、確かにの任意の点間の値を求められるようになっている。
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 q = Integer.parseInt(sa[1]); UnionFind uf = new UnionFind(n + 1); for (int i = 0; i < q; i++) { sa = br.readLine().split(" "); int l = Integer.parseInt(sa[0]) - 1; int r = Integer.parseInt(sa[1]); uf.union(l, r); } br.close(); if (uf.same(0, n)) { System.out.println("Yes"); } else { System.out.println("No"); } } // 以下ライブラリ static class UnionFind { int[] parent, size; int num = 0; // 連結成分の数 UnionFind(int n) { parent = new int[n]; size = new int[n]; num = n; for (int i = 0; i < n; i++) { parent[i] = i; size[i] = 1; } } void union(int x, int y) { int px = find(x); int py = find(y); if (px != py) { parent[px] = py; size[py] += size[px]; num--; } } int find(int x) { if (parent[x] == x) { return x; } parent[x] = find(parent[x]); return parent[x]; } /** * xとyが同一連結成分か */ boolean same(int x, int y) { return find(x) == find(y); } /** * xを含む連結成分のサイズ */ int size(int x) { return size[find(x)]; } } }
ここまで27分34秒+0ペナ。121位。
残り時間はFとGを半々くらいでやっていたがどちらも解けず。
Fはを選ぶ時はも必要という関係でグラフを作るなんてことをやっていて、DPをするにも人の集合を持たずにできる方法がわからなかった。
Gは素数の種類数の情報を扱うTLE解法しか思い付かず。
最終結果:ABCDEの5完1500点、27分34秒、388位、パフォーマンス1980相当
レート変動:2074(Unrated)
なんかUnionFindをちょっと捻っただけくらいの問題はあまり労せず解けることが多いが、やはりDPが足を引っ張っている感じ。
今回はDPができなかったというより初手で違う方向に行き過ぎてしまった感じもするけど。
最近序盤からコケ過ぎだったので、Eまで十分早く解けたことは良かった。