Как отмечалось в комментариях / ответах, проблема в том, что m
и n
не подписаны, поэтому ваши циклы могут останавливаться, только если m
и n
кратны a
.
Если вы посмотрите на вход 6 6 4
(т. Е. M = 6 и a = 4), вы увидите, что m
сначала изменится, как m = 6 - 4
, что приводит к m
, равному 2. Так что в следующемцикл m
изменится как m = 2 - 4
, который должен быть равен -2, но, поскольку m
не подписан, он будет преобразован в очень высокое положительное число (т. е. UINT_MAX-1), и цикл продолжится.Это не то, что вы хотите.
Чтобы исправить это, я предлагаю вам сбросить циклы while
и просто сделать:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
Одна проблема с этим решением состоит в том, что сумма (m + a - 1)
может переполниться (т. е. быть больше, чем UINT_MAX) и, следовательно, дать неправильные результаты.Вы можете исправить это, добавив проверку переполнения перед суммой.
Еще один способ защиты от переполнения может быть:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
Этот код может быть уменьшен до:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}