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;
}
投稿日時:
最終更新: