コンテスト前のレート: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まで十分早く解けたことは良かった。