AtCoder Regular Contest 145
コンテスト前のレート:2026
レート通りのパフォーマンスが得られる順位:304位(1500点、63分59秒)
A - AB Palindrome
問題
下記1.までで11分、3.までで20分かかっていて出だしからボロボロ。
思考過程
- 両端から見ていって、左側が'A'かつ右側が'B'ならアウト、左側が'B'かつ右側が'A'なら操作を行って合わせていく感じ? →4割しか合っていない
- そもそも両端以外はだいたい任意の文字列にできそうな気がしてくる。
- 'A'から始まって'B'で終わる以外は全部可能そう。 →1ケースWA
- コーナーケースを考えてみると、他にあと"BA"だけ駄目なことに気付く。
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)); int n = Integer.parseInt(br.readLine()); char[] s = br.readLine().toCharArray(); br.close(); if (s[0] == 'A' && s[n - 1] == 'B' || n == 2 && s[0] == 'B' && s[1] == 'A') { System.out.println("No"); } else { System.out.println("Yes"); } } }
ここまで24分41秒+2ペナ。1034位。
B - AB Game
思考過程
- ならば、最初にAliceが取れるだけ取れば余りは未満であり、未満でもあるので必ず勝てる。
- の場合だけ一度も取れずに負けるので、その分は引いておく。
- の場合は、とかで実験してみると、の時に勝てる。
- 取れるだけ取った余りが未満なら勝てる模様。
- また、上記1.の考察により、取れるだけ取らないことで勝てるようになることもない。
- 勝ちと負けの並びは周期で繰り返すので、答えはおおよそになるが、最後の周期分は余りが出る可能性があるため、余りとのminを取る。
- WAが出たがすぐに原因がわかりそうにないので、提出デバッグをして駄目なところを絞り込む。
- の中でREを発生させてみると、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(" "); long n = Long.parseLong(sa[0]); long a = Long.parseLong(sa[1]); long b = Long.parseLong(sa[2]); br.close(); if (n < a) { System.out.println(0); } else { if (a <= b) { System.out.println(n - a + 1); } else { long x = n / a; long v1 = b * (x - 1); long y = n % a + 1; long v2 = Math.min(y, b); System.out.println(v1 + v2); } } } }
ここまで39分42秒+4ペナ。607位。
Cは解けず。
とりあえずを作ればよいことはすぐわかったが、それを重複なく数える方法が全然わからず。
括弧列に対応させるというのも全然出てこなかった。
経過時間70分くらいからDも考え始め、90分経過する頃にはもうCが500~600人に通されていたのでDに賭けることにする。
D - Non Arithmetic Progression Set
問題
いつの間にかブラウザ右下に表示されている時刻が実際の時刻より20秒ほど進んでいて、まだ時間が残っているのに諦めそうになった。
思考過程
- とりあえず合計がの条件は一旦忘れて、最小の要素をとして任意の要素が等差数列になっていない集合の作り方を考える。
- これが作れれば、あとは程よく各要素から同じ値を足し引きし、最後のつだけ極端な値にして合計を合わせることでできそう。
- しばらく手作業をしていたが埒が明かないので、可能な最小の値を集合に入れていく貪欲を書いてみる。
- 単純な貪欲では、最大の要素をとするとかかり、では秒ほどかかってを求められた。
- 数列を全部出力してみると文字には収まるくらいだったので、埋め込めるか?と思ったが、少なくとも自分の環境では65536バイト以上だとエラーになってしまい断念。もしかしたらちょっと分割すればいけたかもしれないが。
- 貪欲の出力結果はのようになっており、手作業の時から薄々気付いていたが、個ごとに一気に倍になっている形。
- それなら、の次はから調べる、の次はから調べる、の次はから調べる、のようにしてやれば、無駄がほとんどなくなってになるのではないか。
- 手元ではでもなんとか秒には収まっていそう。
- あとは上記2.の部分を具体的にどうするかだが、貪欲の結果より、最後の要素に(余裕をもってとしておく)以上を足せば非等差数列の条件は守られるはず。
- よって、合計がだいたい程度になるように調整し、最後の要素にから実際の合計を引いた値を加算する。
- 調整値を足すか引くかを実装ミスしていてサンプル以外全てWA。
- 符号を直しつつ、残り時間を確認しながらゆっくり動作確認していたら急にコンテスト終了のお知らせが出てくる。
- でも自分の時計ではまだあと秒くらいあるはず?と思って一応慌てて提出してみたら、119:45でACとなった。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.HashSet; import java.util.Set; 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]); long m = Long.parseLong(sa[1]); br.close(); int[] a = new int[n]; Set<Integer> set = new HashSet<>(); set.add(0); int x = 1; int next = 1; int cnt = 0; // 3 for (int i = 1; i < n; i++) { while (true) { boolean flg = true; for (int j = i - 1; j >= 0; j--) { int val = a[j] - (x - a[j]); if (val < 0) { break; } if (set.contains(val)) { flg = false; break; } } if (flg) { a[i] = x; set.add(a[i]); break; } x++; } // 7 cnt++; if (cnt == next) { x *= 2; cnt = 0; next *= 2; } } long sum = 0; for (int i = 0; i < n; i++) { sum += a[i]; } // 4, 5 // System.out.println(Arrays.toString(a)); // System.out.println(sum); // 10 long g = m - x * 4; long g2 = (g - sum + n - 1) / n; long sum2 = 0; for (int i = 0; i < n; i++) { a[i] += g2; // 11 sum2 += a[i]; } long add = m - sum2; a[n - 1] += add; 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()); } }
ここまで119分45秒+5ペナ。223位。
EとFは問題を開いてもいない。
最終結果:ABDの3完1600点、144分45秒、224位、パフォーマンス2262
レート変動:2026→2052(+26)
2完59分42秒で終わっていたらパフォは1430ほどだったので、今回は立ち回りでパフォ800を稼いだ感じ。
1600点の人はたった14人しかおらず、時間が全然関係なくなったのもおいしかった。
カタラン数とか全然頭に入ってなかったし、自分はやっぱり知識寄りの問題に弱くて構築で時々大当たりがあるタイプなんだなと思う。