【问题标题】:Spoj ROOTCIPH wrong answerSpoj ROOTCIPH 错误答案
【发布时间】:2014-03-05 13:55:06
【问题描述】:

这是 Spoj 问题ROOTCIPH。 我在 C 中通过 2 种方法解决了它。一种方法给出正确答案,另一种方法错误。

我们不会讨论如何解决问题。解决方案很简单。它总是 a*a -2*b。 (考虑三次方程的根......)无论如何,这个问题与它无关。我提供了这个细节,以便人们可以将他们的解决方案运行到源代码并进行更多分析。

现在的问题:

在下面的代码中,如果我用了 long long 而不是 'int',我的答案显示正确,否则 'int' 显示错误。我在 printf 中采用了 %lld,所以即使整数范围超过它也应该处理。

错误代码:

int main()
{
    int  a,b,c;
    int t;

    scanf("%d",&t);

    while(t--)
    {
        scanf("%d%d%d",&a,&b,&c);
        printf("%lld\n",1LL*a*a-2*1LL*b);
    }

    return 0;
}

正确代码:

int main()
{
    long long  a,b,c;
    int t;

    scanf("%d",&t);

    while(t--)
    {
        scanf("%lld%lld%lld",&a,&b,&c);
        printf("%lld\n",a*a-2*b);
    }

    return 0;
}

注意a,b,c的绝对值不会超过10^8。

第一种方法给出了错误的解决方案?您可以在给出的链接中运行解决方案并检查。

根据C operator precedence table* 具有从左到右的关联性。

【问题讨论】:

  • 是否有很大的数字不适合int 而适合long
  • 我用过 1LL ,所以按照优先顺序,得到的答案应该总是 long long
  • 结果将是long long;这没有说明中间值的类型(特别是 a*a)。
  • 如果将错误代码中的 printf 表达式替换为 (1LLa)*a-2*(1LLb) 会怎样?

标签: c


【解决方案1】:

正如@GIJoe 所建议的那样,使用long long 可以容纳比int 更大的数字,这可能是不同之处。比如你的部分表情是a*a;即使你将它乘以 1LL,实际上转换它,损坏可能已经造成。

【讨论】:

  • 但是1LL的乘法发生在a*a的乘法之前。
  • 仅仅因为你把它放在第一位并不(必然)强制执行顺序。编译器是聪明的野兽……
  • 它确实执行了命令。编译器必须符合指定顺序的标准。
  • 除非我看错了,否则就是这样:en.cppreference.com/w/c/language/eval_order
  • 您的链接显示“由于 operator+ 的从左到右的关联性,表达式 a + b + c 被解析为 (a + b) + c”。乘法也是如此。
【解决方案2】:

如果你的答案不在区间 [-2 147 483 648 ; 2 147 483 647 ],那么它不能放入 int 中,它以 32 位存储(如果您在 16 位系统上,则为 16,因此在 [-32 768 ; 32 767] 中)。

long long integer 存储在 64 位上,与您的系统无关。

【讨论】:

  • +1 表示大约 16 位。注意:long long 整数存储在至少 64 位上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 2015-03-25
  • 1970-01-01
相关资源
最近更新 更多