题目一:
题目描述:
验证尼科彻斯定理…即:任何一个整数m的立方都可以写成m个连续奇数之和。 题目来源
例如:
1^3=1
2^3=3+5
3^3=7+9+11
4^3=13+15+17+19
输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。
数据范围:
1≤m≤100
进阶:时间复杂度: O(m) ,空间复杂度:O(1)
输入描述:
输入一个int整数
输出描述:
输出分解后的string
解题思路:
思路一:
写几组例子:
1^3=1 —>1
2^3=3+5 ----> 4
3^3=7+9+11 —> 9
4^3=13+15+17+19 —> 16
我们会发现一个规律:
n x n x n=n x n两边的n个奇数相加。
代码实现:
#include <stdio.h> int main() { int n=0; scanf("%d",&n); int m1=n*(n-1); int m2=n*(n+1); for(int i=m1+1;i<m2-1;i+=2) { printf("%d+",i); } printf("%d",m2-1); return 0; }
思路二:
m的立方,也就是m个m^2 的和相加,m个m^2 可以理解为m个等差为2,首项为m^2-m+1的数列, 即:m2-m+1,m2-m+3, …m2+m-1 共m项
eg: m=6
m1=6x6-6+1 =31
m2=6x6-6+1 +2 =33
m3=6x6-6+1+2+2 =35
m4=6x6-6+1+2+2+2 =37
m5=6x6-6+1+2+2+2+2 =39
m6=6x6-6+1+2+2+2+2+2 = 41
6x6x6=36x6=(36+36+36+36+36+36)=(36-1)+(36+1)+(36-3)+(36+3)+(36-5)+(36+5)
#include <stdio.h> #include <string.h> int main(void) { int m; scanf("%d",&m); int *arr; arr=(int*)malloc(sizeof(int)*m);//分配m个int字节空间 for(int i=0;i<m;i++) { if(i==0) arr[i]=m*m-m+1;// 数列首项a[0] else arr[i]=arr[i-1]+2;//通项:a[n]=a[n-1]+2 } for(int i=0;i<2*m-1;i++) { if(i%2==0) printf("%d",arr[i/2]);//偶数项打印数列 else printf("%c",'+');//奇数项打印“+”号,但是最后项不能打印‘+’号,所以i<2*m-1,而不是i<2*m } return 0; }
思路三:
认真对题目分析,可以将题目转换为:
已知等差数列前n项和,求a0问题。
等差数列求和公式为:Sn=nxa0+1/2n(n-1)d.
本题的公差为2也就是d为2.
由此可输出前n项和。
代码实现:
#include<stdio.h> int main() { int m; scanf("%d",&m); int sn=m*m*m; int a0=sn/m-m+1; printf("%d",a0); for(int i=1;i<m;i++) { printf("+%d",a0+2*i); } printf("\n"); return 0; }
结果情况:
符合题目要求,问题得到解决。
题目二:
题目描述:
等差数列 2,5,8,11,14。。。。(从 2 开始的 3 为公差的等差数列)
输出求等差数列前n项和
数据范围: 1≤n≤1000
输入描述:
输入一个正整数n。
输出描述:
输出一个相加后的整数。
解题思路:
有了第一题的经验。第二题更简单,直接带等差数列求和公式即可。
代码实现:
#include<stdio.h> int main() { int a1 = 2, d = 3, an = 0, n = 0, Sn = 0; while (scanf("%d", &n) == 1) { an = a1 + (n - 1) * d; Sn = (a1 + an) * n / 2; printf("%d", Sn); } }
结果情况:
符合题目要求,问题得到解决。
总结:
今天的两道编程练习题,会发现有一个共同点,那就是都用到了等差数列的相关知识,所以解决有的问题卡主了,我们可以尝试将它转化为一个数学问题,用数学知识解决它。
文章到这里就要告一段落了,有更好的想法或问题,欢迎评论区留言。
希望今天的练习能对您有所收获,咱们下期见!