公式

D - AtCoder Wallpaper 解説 by en_translator


The pattern of the wallpaper is an infinite repetition of this \(4 \times 2\) rectangle. Thus, one can solve this problem by counting for each of the eight \(1 \times 1\) squares how many instance of them is contained in the given rectangle.

In order to count the number of squares at each position, it may be difficult to handle boundaries. As an example, we take the following approach in the sample code below.

  • Count squares along \(x\) and \(y\) axes independently, and multiply it afterward.
  • To count squares along \(x\) axis, take a sufficiently large constant \(P\) that is a multiple of four (such as \(1.1 \times 10^9\)), and compute \((\text{The number of squares between }x = -P\text{ and }x = C) - (\text{The number of squares between }x = -P\text{ and }x = A)\).
    • We pick such \(P\) to avoid issues on rounding-down division toward \(0\).
  • Do the same thing for \(y\) axis.

Also, when debugging this type of problem, it is effective to generate cases by yourself. In this problem, if it is a boundary issue that matters, it is good idea to try many cases for \(0 \leq A, B, C, D \leq 8\).

Sample code (C++):

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

constexpr int mass[2][4] = {
    {2, 1, 0, 1},
    {1, 2, 1, 0}
};
// mass[i][j] : area of rectangle [[j, j + 1], [i, i + 1]] x 2

constexpr i64 inf = 4000000000ll;

int main() {
    // input
    i64 a, b, c, d;
    cin >> a >> b >> c >> d;

    // calculation
    i64 ans = 0;
    for (int fy = 0; fy < 2; ++fy) {
        for (int fx = 0; fx < 4; ++fx) {
            const i64 x1 = (a - fx + 3 + inf) / 4, x2 = (c - fx + 3 + inf) / 4;
            const i64 count_x = x2 - x1; // count along x axis
            const i64 y1 = (b - fy + 1 + inf) / 2, y2 = (d - fy + 1 + inf) / 2;
            const i64 count_y = y2 - y1; // count along y axis
            ans += count_x * count_y * mass[fy][fx];
        }
    }

    // output
    cout << ans << endl;
}

投稿日時:
最終更新: