C语言编程:一个奇葩的累积求和问题——不能用循环实现累加

保尔-科查筋 2014-04-30 01:04:01
问题背景及其要求:
背景:求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比赛的题目。先前我也是很摸不着头脑,总以计算机的思维去分析问题,结果就是没能解决。今天得到高人指点后恍然大悟此题需运用数学方法求解!所以这个故事告诉我们:不要总以一种思维方式去看待问题,换个方式去想,也许就会很简单。
...全文
1040 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
保尔-科查筋 2014-04-30
  • 打赏
  • 举报
回复
谢谢支持哈~
junjie2606 2014-04-30
  • 打赏
  • 举报
回复
分享的不错,思想值得借鉴!赞!
保尔-科查筋 2014-04-30
  • 打赏
  • 举报
回复
本来就是玩具了,这个注重的不是解决实际问题,ACM-ICPC比较注重数据结构和算法思想。这是一个累加的高效算法
sczyq 2014-04-30
  • 打赏
  • 举报
回复
这种比赛的题目,只能是玩具 解决实际问题要复杂得多

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧