はまやんはまやんはまやん

hamayanhamayan's blog

ポスター (Poster) [JOI2019/2020 二次予選ページ A]

https://atcoder.jp/contests/joi2020yo2/tasks/joi2020_yo2_a

解説

https://atcoder.jp/contests/joi2020yo2/submissions/9039879

操作が3種類あるが、大きく塗り替えと回転である。
時計回りに回転させてから、反時計回りに回転させるという動作は無駄なので、
回転操作は「そのまま」「時計回りに1回」「時計回りに2回」「反時計回りに1回」の4通りで固定になる。
塗り替えと回転は独立した操作なので、先に回転しておき、最小の塗替えを考えればいい。
最小の塗り替えは、単に異なる部分を塗り替えればいいので、異なる個数を数えればいい。

あとは、実装であるが、回転操作は自分はライブラリ化してあるので、それを使っている。
添字の管理がちょっと大変なのだが、単純な二重ループに帰着させることができる。
時計回りと反時計回りの2つを実装するのは、大変なので、反時計回りは時計回りを3回やることにする。

int N;
string T[500];
int costs[4] = { 0, 1, 2, 1 };
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> N;
    vector<string> S(N);
    rep(y, 0, N) cin >> S[y];
    rep(y, 0, N) cin >> T[y];

    int ans = inf;
    rep(d, 0, 4) {
        int diff = 0;
        rep(y, 0, N) rep(x, 0, N) if (S[y][x] != T[y][x]) diff++;
        chmin(ans, diff + costs[d]);
        S = rotateClockwise(S);
    }
    cout << ans << endl;
}