首府城市Berland的剧院广场呈矩形 尺寸为n××m米。在城市周年纪念之际, 决定用方花岗岩铺成方形 石板。每个石板的大小为a×a。
铺设广场所需的最少石板数量是多少?它的 允许覆盖比剧院广场更大的表面,但是 正方形必须被遮盖。不允许破坏石板。 石板的侧面应与正方形的侧面平行。
输入
输入在第一行中包含三个正整数:
输入的n, m and a (1 ≤ n, m, a ≤ 10^9)
。输入:
6 6 4
输出
写出所需数量的石板。
#include<stdio.h>
#include<math.h>
int main(){
long long m, n, a;
scanf("%lld %lld %lld", &m, &n, &a);
long long req = ceil(m / a) * ceil(n / a);
printf("%lld", req);
}
它应该在第一个测试用例中给我4
,但它给了我1
。我看到了一个解决方案,人们使用int m, n, a
作为高于main()
的全局声明变量,在这种情况下,如果将10 ^ 18放入4字节全局声明变量中,那么他们如何存储值(假设最后一个测试用例非常大)数)。还是在全局声明变量时有其他规则?其中一些以main(m, n, a)
的形式传递而未声明任何地方。
答案 0 :(得分:2)
您需要将整数取整。
int DivideRoundingUp(int numerator, int denominator)
{
return (numerator+denominator-1) / denominator;
}
使用long long
而不是int
的此版本应提供正确的结果,其参数最大为10 ^ 9
答案 1 :(得分:2)
使用“((1≤n,m,a≤10 ^ 9))”,则不需要double
数学或函数。
由于m / a
是整数除法-舍去了商的小数部分,使得ceil(m / a)
不相关-简单地寻找余数,看看是否应该“舍入上”。
// long long req = ceil(m / a) * ceil(n / a);
long long m_over_a = m/a + (m%a != 0);
long long n_over_a = n/a + (n%a != 0);
long long req = m_over_a * n_over_a;
请注意执行m/a
和m%a
。在过去的几天里,编译器将执行2次昂贵的除法/余数计算。如今,可以期望一个好的编译器看到相邻的代码,并一起执行一个divide_and_remainder计算。因此,m/a
完成后,m%a
的成本通常是无关紧要的。
答案 2 :(得分:1)
int / int 给出整数结果。为避免转换为双精度(尤其是从64位long long型转换)时可能发生的精度问题,您应检查除法的其余部分。
long long req = (m / a + (m%a>0?1:0)) * (n / a +(n%a>0?1:0));
答案 3 :(得分:0)
问题出在m/a
和n/a
的计算中。
由于m
,n
和a
都是整数类型,因此在它们之间执行除法将执行整数除法,这意味着小数部分被截断了。在您的示例中,您正在计算6 / 4
,由于该截断,其求值为1。
您需要将以下参数中的至少一个强制转换为浮点类型,例如double
才能执行浮点除法:
long long req = ceil((double)m / a) * ceil((double)n / a);