问题背景及其要求:
背景:求1 到 n 的累积求和 , 比如当n=100 的时候, 输出5050
要求: 禁止用if , esle ,switch, for, while,do ... while(), 本地打表, 三目运算符, 不能用等差数列求和。输入n,输出结果。
问题分析:
累加求和本是一个极为简单的问题,不用循环,还可以用递归。但是题目还要求不能用if等判断条件!递归也就不行了。而且还不能用数学上的等差数列求和公式! 这该如何求解呢?首先我们来回顾一个数学家的方法:
1+2+3+.........+99+100=?高斯很聪明,他用1+100=101;2+99=101;3+98=101;........;49+52=101;50+51=101。总共50对!答案等于101X50=5050。瞻仰完高人后,开始思考:这是一种简便算法,能不能在这一题发挥作用呢?能。这一题也不外乎用这种方法。首先计算1~n总共可以构成多少对类似于“1+100=101”这种模式的部分和partSum;然后计算这样的部分和有对少个m;其次判断这个数n是否为奇数,若是奇数,则还要求解出这个奇数被分解成多对部分和后剩下的中间数x(比如101的中间数是51,而100就没有中间数,因为它已经被完全分解为“1+100=101”这种模式的部分和,而101单着一个数);最后得出结果partSum*m+x输出。
编程实现:
#include<iostream.h>
void main()
{
int finalNum,sum=0;
cin>>finalNum;
int partSum=1+finalNum;
sum=(finalNum/2)*partSum+finalNum%((finalNum+1)/2)+finalNum%2;
cout<<sum<<endl;
}
解析:
程序很简单,但是想通的话不易 。[size=24px]
第一部分(finalNum/2)*partSum完成:m个部分和(高斯的思路)。
第二部分finalNum%((finalNum+1)/2)完成:若输入的是奇数,取出中间数;n为偶数则此项为0。
第三部分finalNum%2完成: 中间数转换为奇数(加1);没有中间数则此项为0 。[/size]
总结:
这其实是一个ACM-ICPC比赛的题目。先前我也是很摸不着头脑,总以计算机的思维去分析问题,结果就是没能解决。今天得到高人指点后恍然大悟此题需运用数学方法求解!所以这个故事告诉我们:不要总以一种思维方式去看待问题,换个方式去想,也许就会很简单。