问题描述:

输入一个正整数N,输出能相加等于N的联系序列的和(序列必须多于1项),如果这种序列存在,则输出所有这样的序列,如果不存在,则输出NULL。

例如:输入为15
输出:
1+2+3+4+5=15
4+5+6=15
7+8=15

首先我们先分析一下这个问题:
1. 首先1和2是不能表示成连续的自然数之和的,所以我们从3开始
2. 假设n可以表示成连续的自然数之和【s,t】,那么根据求和公式则有(s+t)*(t-s+1)=2*n
3. 把2*n表示成两个自然数相乘,则2*n = a * b
4. 另 s+t=a , t-s+1=b,解方程可得s=(a-b+1)/2, t=(a+b-1)/2
5. 要使得s和t为自然数,那么必须满足a-b和a+b都是奇数
6. 我们在来讨论一下n的奇偶性,如果n是奇数那肯定可以表示为n=2*i+1,至少可以分解为【i,i+1】,所以肯定有解
7. 如果n是偶数,则n可以分解为n=2^i*3^j*….,假定只有i不为0,后面的j,k…幂次都为0,那么所有的因子都为偶数,不可能满足两个因子为奇数的条件。
8. 所以我们可以发现,只要n不是2的幂次并且大于等于3,就一定可以分解为连续正整数之和。

方法1:
使用简单的循环来进行枚举判断,从一个数为1开始枚举,当和大于n时,把第一个数加1,以此类推,此处采用上面推导的n必须为2的幂次直接判断。

参考代码:

#include <stdio.h>int IsCanFind(int n)
{if (n < 3)return 0;return n & (n - 1);//如果n是2的幂次则不能找到
}int main()
{int n, i, j, k, nSum;printf("input a number: ");scanf_s("%d", &n);if (0 == IsCanFind(n)){printf("NULL\n");return 0;}for (i = 1; i < (n + 1) / 2; i++)//只需要找到n的一半就可以了,因为再往下找肯定大于n了{nSum = 0;for (j = i; j <= n; j++){nSum += j;if (nSum == n){if (i == j)break;//这里只有一个元素可以直接退出该层循环,因为后面再加肯定不满足了printf("%d", i);for (k = i + 1; k <= j; k++)printf("+%d", k);printf("=%d\n", n);}else if (nSum > n)break;}}return 0;
}

方法2:
查找的方式相同,只是更换了判断不存在的判断方法。

参考代码:

#include <stdio.h>int main()
{int n, i, j, k, nSum, IsFind = 0;printf("input a number: ");scanf_s("%d", &n);for (i = 1; i <= n; i++){nSum = 0;for (j = i; j <= n; j++){nSum += j;if (nSum == n){if (i == j)break;//这里只有一个元素可以直接退出该层循环,因为后面再加肯定不满足了printf("%d", i);for (k = i + 1; k <= j; k++)printf("+%d", k);printf("=%d\n",n);IsFind = 1;}else if (nSum > n)break;}}if (0 == IsFind)printf("NULL\n");return 0;
}

方法3:
使用序列的起点和终点的两个下标记录,这样可以保证在查找失败之后,不用从头加起,只需要减掉之前的第一个继续往后加就可以了。

参考代码:

#include <stdio.h>int IsCanFind(int n)
{if (n < 3)return 0;return n & (n - 1);//如果n是2的幂次则不能找到
}int main()
{int n, startIndex, endIndex, i, nSum;printf("input a number: ");scanf_s("%d", &n);if (0 == IsCanFind(n)){printf("NULL\n");return 0;}startIndex = 1;endIndex = 2;nSum = startIndex + endIndex;while(startIndex < (n + 1) / 2)//起点到一半即可,因为再往后加肯定超过了{if (nSum == n){if (startIndex < endIndex){for (i = startIndex; i < endIndex; i++)printf("%d+", i);printf("%d=%d\n", endIndex, n);}startIndex++;endIndex = startIndex + 1;nSum = startIndex + endIndex;}else if (nSum > n)//如果已经大于n了,减去起点的数,并且起点右移{nSum -= startIndex;startIndex++;}else{endIndex++;nSum += endIndex;}}return 0;
}

方法4:
使用求和公式来进行求和,省掉了循环的遍历的时间。

参考代码:

#include <stdio.h>int IsCanFind(int n)
{if (n < 3)return 0;return n & (n - 1);//如果n是2的幂次则不能找到
}int main()
{int n, i, j, k, nSum;printf("input a number: ");scanf_s("%d", &n);if (0 == IsCanFind(n)){printf("NULL\n");return 0;}for (i = 1; i < (n + 1) / 2; i++){for (j = 1;; j++) //遍历项数{nSum = (i + i + j - 1) * j / 2;if (nSum == n){if (j == 1)break;//如果只有1项,因为后面再加肯定不满足了printf("%d", i);for (k = i + 1; k <= i + j - 1; k++)printf("+%d", k);printf("=%d\n", n);}else if (nSum > n)break;}}return 0;
}

方法5:
使用我们最开始分析的因子分解法,求出因子必须要满足和为奇数的条件进行求解。

参考代码:

#include <stdio.h>int IsCanFind(int n)
{if (n < 3)return 0;return n & (n - 1);//如果n是2的幂次则不能找到
}int main()
{int n, i, j;int mini, maxi, nStart, nEnd;printf("input a number: ");scanf_s("%d", &n);if (0 == IsCanFind(n)){printf("NULL\n");return 0;}for (i = 1; i * i <= 2 * n; i++){if (2 * n % i == 0){mini = i;maxi = 2 * n / i;if ((mini + maxi) % 2 == 1){nStart = (maxi - mini + 1) / 2;nEnd = (maxi + mini - 1) / 2;if (nStart < nEnd)//大于1个元素再输出{printf("%d", nStart);for (j = nStart + 1; j <= nEnd; j++)printf("+%d", j);printf("=%d\n",n);}}}}return 0;
}

运行结果:

正整数表示为连续自然数的和(难度:1颗星)相关推荐

  1. 连续正整数的和思路c语言,将一个正整数表示为连续自然数的和(附C实现源码)(原创)...

    问题描述:将一个正整数表示为两个或这个两个以上的连续自然数的和.给定一个数,输出所有的可能的结果. 例如: 3=1+2; 9=4+5; 9=2+3+4; 解决方法: 对于给定的整数n,求解基本思路如下 ...

  2. jar包是什么意思_面试难度五颗星:JVM有Full GC,为什么还会 OutOfMemoryError?

    点击上方蓝色"后端面试那些事儿",选择"设为星标" 学最好的别人,做最好的我们 来源:R 大 zhihu.com/question/38511221 问题: R ...

  3. UC浏览器主界面滑动折叠效果 使用自定义behavior实现 难度五颗星*****

    思路:!!!!!!!!!!! RcycleView上的HeadScrollBehavior 思路: 1.让recycleview居于头部的下方 ---方案: 重写layoutDependsOn  让当 ...

  4. 给定一个正整数n,计算有多少个不同的连续自然数段

    给定一个正整数n,计算有多少个不同的连续自然数段,其中自然数的个数至少为2,其和恰为n. u  例如,当n = 27时,有3 个不同的长度大于等于2 的连续自然数段的和恰为27: 2 + 3 + 4 ...

  5. 分解连续自然数的和_将整数分解为连续自然数之和

    将一个正整数,拆分成连续的自然数之和,输出所有可能的情况 例如: 3 = 1+2 10 = 1+2+3+4 18 = 5+6+7 偶然见到这个问题,这里写下自己的解法. 分析: 对给定整数x以及一组满 ...

  6. 一个整数拆分为连续自然数之和

    问题描述:将一个正整数,拆分成连续的自然数之和,输出所有可能的情况 例如: 3 = 1+2 10 = 1+2+3+4 16 = 5+6+7 ... 问题求解: 连续的自然数之和让我们想到了等差数列求和 ...

  7. 1160-1169: 例题5-1-1 连续自然数求和(1160-1169)

    1160: 例题5-1-1 连续自然数求和 题目描述 求1+2+3+...+100,即求 要求用while语句实现 输入 无 输出 要求的和,末尾输出换行. 样例输入 Copy 无 样例输出 Copy ...

  8. 输出和为n的所有的连续自然数序列

    输出和为n的所有的连续自然数序列 如 n = 9: 9 4 5 2 3 4 <编程之美>的题目(2.21只考加法的面试题),去年曾经写过本题的代码,后来不知道把代码放哪里了.按以前的思路, ...

  9. 【枚举】连续自然数和(jzoj 2102)

    连续自然数和 题目大意: 输出一个n,求出所有相加等于n的连续自然数序列 样例输入 10000 样例输出 18 142 297 328 388 412 1998 2002 数据范围限制 10 < ...

最新文章

  1. 阿里90后科学家研发,达摩院开源新一代AI算法模型
  2. 头条创始人张一鸣没有任何大厂经验,是怎么做出这么厉害的产品的呢,以及管理这么大的团队呢?...
  3. AI 发展方向大争论:混合AI ?强化学习 ?将实际知识和常识整合到AI中 ?
  4. 一个网站项目的开始,定位有多重要?
  5. Swift 中枚举、结构体、类(enum、struct、class)
  6. KVM virtio_net之NAPI机制(十七)
  7. 10个Eclipse珍藏插件推荐
  8. spring的aop的动态代理机制都有哪些_Spring学习(4):Spring AOP
  9. Linux centosVMware Tomcat介绍、安装jdk、安装Tomcat
  10. c语言三目运算错误,c语言中三目运算符有什么用
  11. [BUUCTF-pwn]——mrctf2020_shellcode
  12. SQL性能优化工具TKPROF
  13. 自动化流程开源框架BotSharp
  14. 前端学习(1386):多人管理项目6骨架
  15. C语言内存的动态分配
  16. python学了真的很有用吗-会Python的人工作不会太差?编程课真的有必要学吗?
  17. phpexcel 数字格式_将文本转换为phpexcel中的数字格式
  18. @Transactional注解属性(2)
  19. 数据分析师岗位要求案例分析
  20. 滴滴DSRC抢楼大赛,十一快车券飞起来

热门文章

  1. 城市网络安全态势感知工作思路探析
  2. 流程设计器与表单设计器(Wxd.WF,BPM.Foundation,Wxwinter.WF 升级用)
  3. windows 消息处理
  4. 杭电数字电路课程设计——移位寄存器
  5. 筛选质数,埃氏筛和欧拉筛(线性筛)
  6. 【STC12C5A60S2】TOF250(TTL)基于51系列开发板的运用
  7. python 标签云_python 制作标签云
  8. Vue中一些需要注意的点(采坑)
  9. ie不显示html图片不显示,IE浏览器图片显示不出来 IE浏览器图片不显示解决办法...
  10. 数学建模05-元胞自动机