杭电oj1001

杭电oj1001题
杭电oj1001题
首先这是求和,我们有两种思路。
思路一:我们可以通过for循环进行n次累加,每次循环之后,变量加一。
如果代码这样写:

#include <stdio.h>
int main()
{
    int a;
    int sum=0;
    while(scanf("%d",&a)!=EOF){
        for(int i=0;i<=a;i++)
            sum = sum+i;
        printf("%d\n\n",sum);
    }
    return 0;
}

oj评判的是wrong answer
(出现wrong answer原因:
对于部分或者全部的测试数据都没有输出正确的结果
可以考虑:
算法的正确性和鲁棒性)

那么为什么sum置0要放while里呢?置0就要说到上篇文章杭电oj1000,写到分四种输入输出,这题也是第二种。所以它是输入一系列的数,会输出一系列的和,所以每次计算下一组时,就要在while里重置sum的值。
修改后的代码如下:

#include <stdio.h>
int main()
{
    int a,sum;
    while(scanf("%d",&a)!=EOF){
        sum=0;
        for(int i=0;i<=a;i++)
            sum = sum+i;
        printf("%d\n\n",sum);
    }
    return 0;
}

思路二:由数学基本知识,等差数列求和公式:首项加末项乘以项数除以2。
如果代码这样写:

#include<stdio.h>
int main()
{
    int n,sum;
    while(scanf("%d",&n)!=EOF)
    {
        sum=(n+1)*n/2;
        printf("%d\n\n",sum);
    }
    return 0;
}

oj评判的是wrong answer

因此这里出现了乘法溢出的问题,在这里不能直接用等差数列求和公式,因为题中说:
You may assume the result will be in the range of 32-bit signed integer.
要求是求和之后的结果不能超过32位,

假设结果是一个32位的有符号整数,也就是说最大值是有符号整数范围要在-2的31次方到2的31次方-1之间,假设sum为2的31次方,那么根据sum=(n+1)*n/2可以大致得到n的大约取值是2的16次方,意味当n>=2的36次方就会溢出。对于部分测试数据会出错,所以前者无法通过测试。

也就是说,假设n*(n+1)/2的结果刚好满足32位。但是在做除法前n*(n+1)的结果就已经超过了32位。

若真的想用公式法,其实也可以,需要把除以2的运算拿到前面来,这样的话,就要判断一下输入是不是偶数了。
先判断奇偶,然后把n和n+1中偶数的一方除以二,再相乘,这样就不会溢出了。

修改后的代码:

#include<stdio.h>
int main()
{
    int n,sum;
    while(scanf("%d",&n)!=EOF)
    {
        if(n%2==0)
            sum=n/2*(n+1);
         else
            sum=(n+1)/2*n;
        printf("%d\n\n",sum);
    }
    return 0;
}

此外,注意一些小细节,控制一下格式。

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值