AtCoder Regular Contest 153

コンテスト前のレート:2043
レート通りのパフォーマンスが得られる順位:369位(1400点、115分49秒)

A - AABCDDEFE

問題

思考過程
  1. 9桁の整数全探索はTLE。
  2. 3桁は他と同じ値なので6桁全探索すればよさそう。
  3. 実際にループを回すまでもなく、100000から数えてN番目の数は100000+N-1で求められる。
  4. 上記3.で求めた数にS_9, S_6, S_2を挿入する。
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());
        br.close();

        int x = 100000 + n - 1;
        StringBuilder sb = new StringBuilder();
        sb.append(x);
        sb.append(sb.charAt(4));
        sb.insert(3, sb.charAt(3));
        sb.insert(0, sb.charAt(0));
        System.out.println(sb.toString());
    }
}

ここまで4分08秒+0ペナ。210位。


B - Grid Rotations

問題

思考過程
  1. サンプルの図を見ながら、行と列を独立に見てよいことを確認する。
  2. 手元で実験する。0(H-1)を並べ、aを適当に決めて何回か動かしてみる。
  3. i番目の要素について、a未満の部分はa-iに、a以上の部分はH+a-iに移動していることがわかる。
  4. この変換をQ回合成する。
  5. (H+a-i) \% Hに移動するとすれば、場合分けは不要になる。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

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 h = Integer.parseInt(sa[0]);
        int w = Integer.parseInt(sa[1]);
        char[][] s = new char[h][w];
        for (int i = 0; i < h; i++) {
            s[i] = br.readLine().toCharArray();
        }
        int q = Integer.parseInt(br.readLine());
        int[] a = new int[q];
        int[] b = new int[q];
        for (int i = 0; i < q; i++) {
            sa = br.readLine().split(" ");
            a[i] = Integer.parseInt(sa[0]) - 1;
            b[i] = Integer.parseInt(sa[1]) - 1;
        }
        br.close();

        // (X, Y) -> (x1 * X + x2, y1 * Y + y2)に移動するとする
        int x1 = 1;
        int y1 = 1;
        int x2 = 0;
        int y2 = 0;
        for (int i = 0; i < q; i++) {
            x1 *= -1;
            y1 *= -1;
            x2 = (h + a[i] - x2) % h;
            y2 = (w + b[i] - y2) % w;
            if (x2 < 0) x2 += h;
            if (y2 < 0) y2 += w;
        }

        char[][] t = new char[h][w];
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                int x = (i * x1 + x2 + h) % h;
                int y = (j * y1 + y2 + w) % w;
                t[x][y] = s[i][j];
            }
        }

        PrintWriter pw = new PrintWriter(System.out);
        for (int i = 0; i < h; i++) {
            pw.println(t[i]);
        }
        pw.flush();
    }
}

ここまで21分51秒+0ペナ。154位。



残り時間は全てCに費やしたが解けず。
両端以外をとりあえず1(N-2)で埋めて、両端の符号や中央(N-2)個の合計値によって場合分けすることを基本方針としていたが、両端の符号が異なる場合などに上手く調整ができず、例3以外のケースは全て構成可能だろうと思い込んでいたこともあって収拾がつかなくなっていた。



終結果:ABの2完800点、21分51秒、531位、パフォーマンス1850
レート変動:2043→2025(-18)


2完内ではかなり上の方だったので最低限の傷で済んだ。

いくらやる気がなくても最低限青diff以下だけは全問追いかけておきたいと思っているので、翌日Cを解説ACだけはした。
こういうのは適当な思い付きでやろうとしてしまうので、解説のような解き方は自力でできる気は全然しない。