long long int Объявлено внутри main () - PullRequest
0 голосов
/ 04 октября 2018

Театральная площадь в столице Берляндии имеет прямоугольную форму размером 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);    
}

Itдолжен дать мне 4 в первом тестовом случае, но он дает мне 1.Я видел решение, в котором люди использовали int m, n, a как глобально объявленные переменные, которые выше main() в этом случае, как они сохраняют значение, если 10 ^ 18 в 4-байтовой глобально объявленной переменной (предположим, что последний тестовый случай очень большой).Или есть другое правило, когда мы объявляем переменную глобально?Некоторые из них проходили как main(m, n, a), нигде не объявляя.

Ответы [ 4 ]

0 голосов
/ 05 октября 2018

С "(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 дорогих вычисления деления / остатка.Сегодня разумно ожидать, что хороший компилятор увидит смежный код и вместе выполнит одно вычисление div_and_remainder.Таким образом, после завершения m/a стоимость m%a, как правило, несущественна.

0 голосов
/ 04 октября 2018

int / int дает целочисленный результат.Чтобы избежать проблем с точностью, которые могут возникнуть при приведении к удвоению, особенно из длинного 64-битного кода, вы должны проверить остаток от деления.

long long req = (m / a + (m%a>0?1:0)) * (n / a +(n%a>0?1:0));
0 голосов
/ 04 октября 2018

Вам нужно целочисленное деление, которое округляется в большую сторону.

int DivideRoundingUp(int numerator, int denominator)
{
    return (numerator+denominator-1) / denominator;
}

Версия с использованием long long вместо int должна обеспечивать правильные результаты с параметрами до 10 ^ 9

0 голосов
/ 04 октября 2018

Проблема заключается в вычислении m/a и n/a.

Поскольку m, n и a являются целочисленными типами, при выполнении деления между ними выполняется целочисленное деление , означающее, что и дробная часть усекается.В вашем примере вы вычисляете 6 / 4, который оценивается как 1 из-за этого усечения.

Вам необходимо привести хотя бы один из этих аргументов к типу с плавающей запятой, например double, чтобы выполнитьделение с плавающей запятой:

long long req = ceil((double)m / a) * ceil((double)n / a);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...