循环输入,每输入一个正整数n(n ≤ 65535), 输出1 + 2 + 3 + … + n 的值,并且多输出一个空行。当没有任何输入时,结束 程序。
我们可以通过暴力枚举或者使用等差数列前n项和的公式来计算出来结果
# include
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
int ans = n * (n + 1) / 2;
printf("%d\n",ans);
}
return 0;
}
这里为什么出错了呢?逻辑是正确的呀?
这里的n是小于等于65535的,当n是65535的时候,那么n * (n + 1)已经溢出了,因为65535 可以看作是(216-1),那么可以自行计算一下n * (n + 1)的值,会大于int 所能表示的最大值231-1,所以这种方法没有考虑到溢出,所以会出错。
#include
int main()
{
int n = 1;
while(scanf("%d",&n) != EOF)
{
int sum = 0;//(1)
while(n)
{
sum += n;
n--;
}
printf("%d\n",sum);
}
return 0;
}
#include
int main()
{
int n;
int sum = 0;
while(scanf("%d",&n) != EOF)
{
if (n % 2 == 0) //(1)
{
sum = n /2 * (n + 1);
}
else //(2)
{
sum = (n + 1) / 2 * n;
}
printf("%d\n",sum);
}
return 0;
}
总之,这里按照奇数和偶数分情况输出,是因为计算机中,计算除法是向下取整的,所以分奇偶情况来讨论的话,那么就不会因为计算机这种计算方法从而导致结果出错了。
由于边界溢出问题,所以我们才会考虑这么多的。那么我们扩大一下存储结果的范围,那么就不用这么辛苦地考虑边界溢出问题了。
由于C语言中有无符号整型这种数据类型,它的存储范围是[0.232-1],这个题目中最大的范围是n * (n + 1),可以自己手动计算一下,n * (n + 1)的范围是小于无符号整型的最大表示范围的,所以我们可以使用无符号整型来存放结果而不用担心溢出。
#include
int main()
{
int n;
while( scanf("%d",&n) != EOF )
{
unsigned int sum = 0;
sum += n * (n + 1) / 2;
printf("%u\n",sum);//(1)
}
return 0;
}
我们可以考虑使用可以表示更大范围的数据类型来存储最后的结果,比如说这里使用 long long, long long 数据类型在C中可以表示的范围是: [- 263 , 263 -1],那么足以表示我们这道题目的结果了。
#include
int main()
{
int n;
while( scanf("%d",&n) != EOF )
{
long long sum = 0;
sum = n * (n + 1) / 2;
printf("%lld\n",sum);//(1)
}
return 0;
}
由于该文章是读了CSDN博主英雄哪里出来
后自己的一些总结,希望可以帮助到大家。英雄哪里出来
的对应文章在这里:传送门。