一题简单的oj好题大一

img

普通版本:O(n)


#include<iostream>
#define MAXSIZE 40
using namespace std;

//double 精度高,有效数字 15-16 位,float 精度低,有效数字 6-7位,
//但是 double 消耗的内存是 float 的两倍,
//运算速度比 float 慢得多,建议能用 float 保证精度的就用 float,少用 doubledouble Array[MAXSIZE];//先用double的看能不能过时间,不能就该用float

void init() {
    //递归比迭代花费的时间会比较长
    for (int i = 0; i < MAXSIZE; i++) {
        Array[i] = i <= 1 ? 1 : Array[i - 1] + Array[i - 2];
    }
}
int main() {
    init();//一次生成,不再递归
    int n,i;
    double result;
    while (cin >> n) {
        result = 0;
        for (i = 0; i < n; i++) {
            result += Array[i + 2] / Array[i+1];
        }
        printf("%.6lf\n", result);//保持六位小数
    }
}

优化版本 O(1)

#include<iostream>
#define MAXSIZE 40
using namespace std;
//double 精度高,有效数字 15-16 位,float 精度低,有效数字 6-7位,
//但是 double 消耗的内存是 float 的两倍,
//运算速度比 float 慢得多,建议能用 float 保证精度的就用 float,少用 doubledouble Array[MAXSIZE];//先用double的看能不能过时间,不能就该用float
//double resultItems[MAXSIZE];
double resultComSum[MAXSIZE-1];//这里最大的为38个>题意的36,够用,1-37使用范围
void init() {
    //递归比迭代花费的时间会比较长
    double tmp=0;
    for (int i = 0; i < MAXSIZE; i++) {
        Array[i] = i <= 1 ? 1 : Array[i - 1] + Array[i - 2];
        if (i > 1) {
            //resultItems[i - 2] = Array[i] / Array[i - 1];  
            tmp += Array[i] / Array[i - 1];
            resultComSum[i -1] = tmp;
        }
    }
}
int main() {
    init();//一次生成,不再递归
    int n;
    double result;
    while (cin >> n) {
        result = resultComSum[n];
        printf("%.6lf\n", result);//保持六位小数
    }
}

分子和分母都是是斐波那契数列

#include <stdio.h>
#include <stdlib.h>

int main() {

    double sum=0.0;
    int n;
    printf("请输入n:");
    scanf("%d",&n);
    for (int i = 1; i <= n; i++) {
        sum+=(float)fbi(i+2)/fbi(i+1);
    }
    printf("%f",sum);
    return 0;
}

int fbi(int n) {
    if(n==1||n==2) {
        return 1;
    }
    return fbi(n-1)+fbi(n-2);
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int n = 0, i = 0;
    while (scanf("%d", &n))
    {
        double* a = (double*)malloc(sizeof(double) * (n + 2));
        double sum = 0;
        for (i = 0; i < n + 2; i++)
        {
            a[i] = (i == 0 || i == 1) ? 1 : a[i - 2] + a[i - 1];
        }
        for (i = 0; i < n; i++)
        {
            sum += a[i + 2 ] / a[i + 1 ];
        }
        printf("%lf\n", sum);
    }
    return 0;
}

img

因为数列的各项可以递推,而最终结果只是求和,所以完全可以不用数组,只用几个变量做递推计算就能完成。
如果出题的意图是要求用递推完成,那么测试点必然会有个足够大的n,使得用数组计算会出现内存异常。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    double fn, fn1, fn2;
    int n, i;
    double xn, sum;

    while (scanf("%d", &n) > 0) {
        sum = 0.0;
        fn = 1.0;
        fn1 = 2.0;
        for (i = 0; i < n; ++i) {
            xn = fn1 / fn;
            sum += xn;
            fn2 = fn + fn1;
            fn = fn1;
            fn1 = fn2;
        }
        printf("%.6lf\n", sum);
    }

    return 0;
}