平整广场

GitHub跳转原题关系图返回列表

允许石板伸出边界时,铺满 n×m 广场最少需要 ⌈n/a⌉×⌈m/a⌉ 块 a×a 石板。

OJ: roj

题目 ID: 20002

难度:入门

标签:数学整除

创建: 2026-10-02 19:16

更新: 2026-10-06 02:11

题目描述

广场是 n×mn \times m 的矩形,要用 a×aa \times a 的正方形石板铺满。石板不能切割、不能重叠,边必须与广场边平行,但可以伸出边界。求最少石板数。数据范围:1≤n,m,a≤1091 \le n,m,a \le 10^9。

思路

石板边平行广场边时,长、宽两个方向互不影响。铺满长度为 nn 的边至少需要 ⌈n/a⌉\lceil n/a \rceil 块;同理高度方向需要 ⌈m/a⌉\lceil m/a \rceil 块。把两个方向的最少块数相乘即可取到下界,因此答案为 ⌈n/a⌉×⌈m/a⌉\lceil n/a \rceil \times \lceil m/a \rceil。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-02 19:16
# update_at: 2026-10-02 19:16

import sys


def count(length: int, stone: int) -> int:
    """铺满长度为 length 的边需要几块边长 stone 的石板:整数上取整 ⌈length/stone⌉。"""
    return (length + stone - 1) // stone


def solve() -> None:
    n, m, a = map(int, sys.stdin.buffer.read().split())
    print(count(n, a) * count(m, a))


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-06 02:11
 * update_at: 2026-10-06 02:11
 */

#include <cstdio>
#include <iostream>
using namespace std;

typedef long long ll;

// 铺满长度为 len 的边需要多少块边长为 a 的石板:整数上取整
ll need(ll len, ll a) {
    return (len + a - 1) / a;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ll n, m, a;
    cin >> n >> m >> a;

    // 长、宽两个方向分别上取整后相乘
    cout << need(n, a) * need(m, a) << "\n";
    return 0;
}