Редакция для Мощение площади
Submitting an official solution before solving the problem yourself is a bannable offence.
Автор:
1. Идея
Нужно покрыть прямоугольник n x m квадратными плитками a x a.
Так как плитки можно выкладывать с выходом за границы площади, нам не нужно точно "вписывать" их внутрь. Достаточно понять:
- сколько плиток нужно по длине
n, - сколько плиток нужно по ширине
m.
Если по одной стороне требуется x плиток, а по другой y, то всего понадобится x * y плиток.
Главная задача — правильно посчитать x и y, то есть округлить деление вверх.
2. Наблюдения
Наблюдение 1
Если длина стороны равна n, а сторона плитки равна a, то количество плиток по этой стороне равно:
n / a, еслиnделится наaбез остатка;- иначе на одну больше.
Например:
- для
n = 8,a = 4нужно2плитки; - для
n = 9,a = 4нужно3плитки.
Это и есть округление вверх от n / a.
Наблюдение 2
Округление вверх для целых чисел удобно считать формулой:
(n + a - 1) / a
в C++ для целочисленного деления, или
(n + a - 1) // a
в Python.
Наблюдение 3
Ответ может быть большим.
Например, если n = m = 10^9 и a = 1, то ответ равен 10^18.
Поэтому в C++ нужно использовать тип long long.
3. Алгоритм
- Считать
n,m,a. - Посчитать количество плиток по первой стороне:
x = (n + a - 1) / a
- Посчитать количество плиток по второй стороне:
y = (m + a - 1) / a
- Вывести
x * y.
4. Почему это работает
Рассмотрим одну сторону длины n.
Одна плитка закрывает a метров этой стороны.
Две плитки закрывают 2 * a,
три — 3 * a, и так далее.
Нужно найти минимальное число плиток x, для которого:
x * a >= n
То есть плиток должно хватить, чтобы покрыть всю длину, даже если последняя плитка немного выйдет за границу.
Минимальное такое x — это как раз округление вверх от n / a.
Аналогично для второй стороны получаем y.
После этого прямоугольник покрывается сеткой из x плиток по горизонтали и y плиток по вертикали. Всего таких плиток:
x * y
Меньше взять нельзя, потому что хотя бы по каждой стороне нужно не меньше x и y плиток соответственно.
Значит, найденное количество минимально.
5. Сложность
Алгоритм выполняет несколько арифметических операций.
- Время:
O(1) - Память:
O(1)
6. Код на C++17
#include <iostream>
using namespace std;
int main() {
long long n, m, a;
cin >> n >> m >> a;
long long x = (n + a - 1) / a;
long long y = (m + a - 1) / a;
cout << x * y << '\n';
return 0;
}
7. Код на Python 3
n, m, a = map(int, input().split())
x = (n + a - 1) // a
y = (m + a - 1) // a
print(x * y)
Комментарии