首页 > 编程知识 正文

杭电oj1001题目的意思,杭电OJ1106

时间:2023-05-06 09:04:17 阅读:206308 作者:4765

杭电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("%dnn",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("%dnn",sum); } return 0;}

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

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

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

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。