题目的主要信息:

  • 任何一个整数m的立方都可以写成m个连续奇数之和

    • 13=11^3=1

    • 23=3+52^3=3+5

    • 33=7+9+113^3=7+9+11

    • 43=13+15+17+194^3=13+15+17+19

  • 输入一个正整数m,将m的立方写成m个连续奇数之和的形式输出

方法一:遍历查找

具体做法:

可以发现上述每个整数m的奇数和共有m个奇数,而且是连续的奇数,那我们假设第一个数为ii,可以通过等比数列求和得到连续奇数之和为:mi+m(m1)m * i + m *(m-1),即我们遍历1到m3m^3,找到满足上述等差数列之和等于三次幂的第一个数,然后输出以它开始的连续的m个奇数即可。

#include<iostream>
#include<string>
using namespace std;

int main(){
    int m;
    while(cin >> m){
        int pow = m * m * m; //先获取三次方的值
        for(int i = 1; i < pow; i += 2){ //从1开始找到pow
            if(m * i + m * (m - 1) == pow){ //比较等差数列和与三次幂是否相等
                cout << i; //相等开始输出连续m个数字
                for(int j = 1; j < m; j++)
                    cout << '+' << i + 2 * j;
                cout << endl;
                break;
            }
        }
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(m2)O(m^2),从方法二可以得知第一个开始的数其实等于mm(m1)m * m - (m - 1),那我们总共需要遍历mm(m1)+mm * m - (m - 1)+m
  • 空间复杂度:O(1)O(1),遍历直接输出,无额外空间

方法二:数学规律

具体做法:

我们也可以寻找第一个数与m之间的规律,直接锁定第一个数。

如下图所示:

alt

不难发现,第一个数等于mm(m1)m * m - (m - 1),那我们只要从这个数开始连续遍历输出m个奇数即可。

#include<iostream>
#include<string>
using namespace std;

int main(){
    int m;
    while(cin >> m){
        int odd = m * m - (m - 1); //根据公式获取起点奇数
        cout << odd;
        for(int i = 1; i < m; i++) //遍历后续m-1个奇数
            cout << '+' << odd + 2 * i; //输出
        cout << endl;
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(m)O(m),一共遍历mm
  • 空间复杂度:O(1)O(1),遍历直接输出,无额外空间