长整型int变量无输出

时间:2019-06-07 11:08:20

标签: c long-integer

这是一个代码段:

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:

因此,我在下面提供主要问题的链接。我的代码逻辑对我来说似乎是正确的。

https://codeforces.com/contest/1/problem/A

3 个答案:

答案 0 :(得分:3)

正如评论/答案中指出的那样,问题是mn是无符号的,因此只有在mn为整数时,循环才能停止的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);
    }
}