long long int 变量没有输出

No output for long long int variables

这是一个代码片段:

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 的部分有问题。但我不知道如何修复它。我正在使用代码块。

相应输入的一些预期输出如下:

Input: 6 6 4

输出:4

Input: 1000000000 1000000000 1

输出:1000000000000000000(10^18)。

追加:

所以,我给出下面主要问题的link。我的代码逻辑对我来说似乎是正确的。

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

while(m>0){
    m-=a;
    p++;
}

将 运行 直到 m 等于 0,因为它不能为负数,因为它是无符号的。所以如果 m 是 4 并且 a 是 6,那么 m 将下溢并得到 m 可以容纳负 2 的最大值。您应该将输入变量更改为有符号.

4386427 显示了如何使用数学来完全删除循环,但对于更一般的情况,您可以这样做:

while(m > a) {
    m-=a;
    p++;
}
// The above loop will run one iteration less
m-=a;
p++;

当然,你需要为第二个循环做同样的事情。

另一件事,检查 scanf 的 return 值:

if(scanf("%u%u%u",&m,&n,&a) != 3) {
    /* Handle error */
}

正如在 comments/answers 中指出的那样,问题是 mn 是无符号的,所以只有在 m 和 [=14= 时你的循环才能停止] 是 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;
  }

使用 unsigned 类型并不总是表示正值的最佳选择,特别是当不需要其模块化行为时(并且可能被遗忘,这会导致 "unexpected" 错误)。 OP 的用例需要一个能够存储最大 109 值的整数类型,该值在 32 位有符号整数的范围内(肯定是 long int) .

正如 4386427 的回答所示,OP 代码中的 while 循环无论如何都可以(并且应该)避免,除非以某种方式需要 "brute force" 解决方案(这不太可能鉴于问题的来源)。

不过我会使用一个函数:

#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);
    }
}