acmcoder1001:Sum Problem细节问题

先来看看这个问题:

Input
The input will consist of a series of integers n, one integer per line.
Output
For each case, output SUM(n) in one line, followed by a blank line. You may assume the result will be in the range of 32-bit signed integer.
Sample Input
1
100
Sample Output
1

5050
当时一卡这个题目,觉得太简单了,可能常规做法就是用for循环累加,但是比较耗时,可以用数学神童高斯的公式来解决。然后很牛气的开始写起代码(牛气的是自己不仅想到了常规做法和他的缺点,还想到了优化方法,呵呵~这点出息……),代码如下:

#include 
using namespace std;
int main()
{
	int n;
	while(cin>>n)
	{
		cout<<(1+n)*n/2<

提交之后,却发现结果是wrong answer。顿时懵了,这么简单的代码都会错,之后再看原题,有这么一句:You may assume the result will be in the range of 32-bit signed integer.原来问题出在这里,计算结果都存在32位的int里,这也包括中间结果:(1+n)*n/2。也就是说在计算过程中发生了溢出,恍然大悟!接下来思考该怎么解决:

方案一:使用老方法,for循环累加;

方案二:既然是中间计算结果发生溢出,那就找出中间计算公式,看能不能改成不溢出。首先看公式(1+n)*n/2,先做乘法运算后作除法运算,乘法是发生溢出的罪魁祸首,然而除法不可能发生溢出(如果是在汇编中,也会溢出)。那么就可以考虑先做除法,先将中间结果变小就行了。但是做除法还要考虑的就是要小心类型的隐式转换:如果是奇数作除法,结果会有偏差,因为题设是中间结果保存在int型变量中。一次可以将输出作如下改进:

cout<<((n%2==0)?n/2*(1+n):(1+n)/2*n)<


提交代码,Accept!

心得:以后做题要看清题目,这是从小学老师开始就强调的问题!

你可能感兴趣的:(C/C++)