这是一个代码段:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
以上代码不适用于任何输入。就是说,尽管我不明白我在哪里弄错了,但它似乎已经崩溃了。我想printf中带有%lld 的部分有问题。但是我不知道如何解决它。我正在使用代码块。
相应输入的一些预期输出如下:
输入:6 6 4
输出:4
输入:1000000000 1000000000 1
输出:1000000000000000000(10 ^ 18)。
APPEND:
因此,我在下面提供主要问题的链接。我的代码逻辑对我来说似乎是正确的。
答案 0 :(得分:3)
正如评论/答案中指出的那样,问题是m
和n
是无符号的,因此只有在m
和n
为整数时,循环才能停止的a
。
如果查看输入6 6 4
(即m = 6和a = 4),则可以看到m
首先将像m = 6 - 4
那样变化,从而导致{{1} }为2。因此,在下一个循环中,m
会像m
那样改变,该值应为-2,但是由于m = 2 - 4
是无符号的,它将换成非常高的正数(即UINT_MAX-1 ),循环将继续。那不是你想要的。
要解决此问题,我建议您放下m
循环并简单地做:
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);
可能溢出(即大于UINT_MAX),因此得出错误的结果。您可以通过在执行总和之前添加溢出检查来解决此问题。
防止溢出的另一种方法可能是:
(m + a - 1)
此代码可以简化为:
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;
}
答案 1 :(得分:1)
while(m>0){
m-=a;
p++;
}
将一直运行到m
等于0,因为它不能为负,因为它是无符号的。因此,如果m
为4,而a
为6,则m
将下溢并获得m
可以容纳的最大值减去2。您应将输入变量更改为signed
4386427显示了如何使用数学方法完全删除循环,但是对于更一般的情况,您可以这样做:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
当然,您需要为第二个循环做同样的事情。
另一件事,检查scanf
的返回值:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
答案 2 :(得分:0)
使用unsigned
类型并不总是代表正值的最佳选择,尤其是在不需要其模块化行为时(尤其是在忘记了行为的情况下,这会导致“意外的”错误)。 OP的用例需要一个整数类型,该类型必须能够存储最大10 9 的值,该值在32位带符号整数(肯定是long int
)的范围内。>
正如4386427的答案所示,无论如何(或应该)避免OP代码中的while
循环,除非以某种方式需要“蛮力”解决方案(这种情况不太可能,给出问题的来源)。
我会使用一个函数,
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}