C语言简单例题——循环结构(3)数列

本文介绍了使用C语言计算斐波那契数列、调和级数、调和三角形、幸运数序列、泰勒级数中cos(x)的前n项之和以及Ulam数列的方法。详细阐述了每种序列的定义和计算思路,并提供了相应的参考代码。

输入一个正整数n,计算斐波那契数列中第n项的值。

思路:

(1)斐波那契数列的定义:f(0) = 0, f(1) = 1, f(n) = f(n-1) + f(n-2) (n>=2)。

(2)由于斐波那契数列中每一项都依赖其前面两项的值,因此可以使用递归的方式求解,即先求出前面两项的值,然后根据它们求出第n项的值。

以下是一份参考代码:

#include <stdio.h>

int fib(int n)
{
    if(n == 0 || n == 1)
    {
        return n;
    }
    else
    {
        return fib(n-1) + fib(n-2);
    }
}

int main()
{
    int n;
    printf("请输入一个正整数:\n");
    scanf("%d", &n);

    int res = fib(n);
    printf("斐波那契数列第%d项的值为%d\n", n, res);

    return 0;
}

输入一个正整数n,计算调和级数的前n项之和。调和级数的第n项定义为1/1 + 1/2 + … + 1/n。

思路:

(1)调和级数的定义:H(n) = 1/1 + 1/2 + … + 1/n。

(2)由于调和级数中每一项的值是通过分数相加得到的,因此可以使用循环从1到n遍历每一项,并将它们相加得到总和。

以下是一份参考代码:

#include <stdio.h>

double harmonic(int n)
{
    double res = 0;
    for(int i = 1; i <= n; i++)
    {
        res += 1.0 / i;
    }
    return res;
}

int main()
{
    int n;
    printf("请输入一个正整数:\n");
    scanf("%d", &n);

    double res = harmonic(n);
    printf("调和级数前%d项之和为%.6f\n", n, res);

    return 0;
}

输入一个正整数n,计算调和三角形中第n行、第一个元素的值。调和三角形的第n行定义为1/1, 1/2+1/3, 1/4+1/5+1/6, …, 1/(m*(m-1)+1)+…+1/m*(m+1), …。

思路:

(1)调和三角形的定义:H(i,j)表示调和三角形中第i行、第j个元素的值,其中H(1,1)=1,H(i,j)=H(i-1,j)+1/(m*(m-1)+1)+…+1/m*(m+1),其中m=(i-1)*j+j。

(2)由于调和三角形中每一行的元素值是通过前一行元素值和新加入的分数相加得到的,因此可以使用两重循环从2到n遍历每一行和每个元素,并根据它们的位置计算出对应的分数值,然后将它们相加得到第n行、第一个元素的值。

以下是一份参考代码:

#include <stdio.h>

double harmonic_triangle(int n)
{
    double res = 1;
    for(int i = 2; i <= n; i++)
    {
        int m = (i - 1) * 1 + 1; // 第i行第1个元素对应的m
        double sum = 0;
        for(int j = 1; j <= i; j++)
        {
            sum += 1.0 / m;
            m++;
        }
        res = sum;
    }
    return res;
}

int main()
{
    int n;
    printf("请输入一个正整数:\n");
    scanf("%d", &n);

    double res = harmonic_triangle(n);
    printf("调和三角形第%d行第1个元素的值为%.6f\n", n, res);

    return 0;
}

输入一个正整数n,计算“幸运数”序列中第n项的值。幸运数序列是指将自然数序列进行筛法(从2开始,每次去掉序列中所有可以被当前未被删去的最小的数整除的数),最后剩下的序列就是幸运数序列。

思路:

(1)幸运数序列的定义:L(n)表示幸运数序列中第n个元素的值。

(2)由于幸运数序列中每一项的值是通过删除前面的元素得到的,因此可以使用循环从2到n遍历每一项,并在每一轮循环中执行一次筛法,将不符合条件的数删除,最后剩下的数即为第n项的值。

以下是一份参考代码:

#include <stdio.h>
#include <stdbool.h>

int lucky(int n)
{
    bool a[n+1];
    for(int i = 2; i <= n; i++)
    {
        a[i] = true;
    }
    for(int i = 2; i <= n; i++)
    {
        if(a[i])
        {
            for(int j = 2; i*j <= n; j++)
            {
                a[i*j] = false;
            }
        }
    }
    int res = 0, count = 0;
    for(int i = 2; i <= n; i++)
    {
        if(a[i])
        {
            count++;
            if(count == n)
            {
                res = i;
                break;
            }
        }
    }
    return res;
}

int main()
{
    int n;
    printf("请输入一个正整数:\n");
    scanf("%d", &n);

    int res = lucky(n);
    printf("幸运数序列第%d项的值为%d\n", n, res);

    return 0;
}


输入一个正整数n和一个实数x,计算泰勒级数中cos(x)的前n项之和。cos(x)的泰勒级数展开公式为:cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + …。

思路:

(1)cos(x)的泰勒级数展开公式:cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + …。

(2)由于泰勒级数中每一项的值是通过前一项乘以一个常数得到的,因此可以使用循环从0到n-1遍历每一项,并根据它们的位置计算出对应的常数值和幂次方值,然后将它们相加得到前n项之和。

以下是一份参考代码:

#include <stdio.h>
#include <math.h>

double cos_taylor(int n, double x)
{
    double res = 1;
    for(int i = 1; i <= n-1; i++)
    {
        double temp = pow(-1, i) * pow(x, 2*i) / tgamma(2*i+1);
        res += temp;
    }
    return res;
}

int main()
{
    int n;
    double x;
    printf("请输入一个正整数n和实数x:\n");
    scanf("%d%lf", &n, &x);

    double res = cos_taylor(n, x);
    printf("cos(%.2f)的泰勒级数前%d项之和为%.6f\n", x, n, res);

    return 0;
}

输入一个正整数n,计算Ulam数列中第n项的值。Ulam数列是指从1开始,每一项都是由前面的项中取出两个不同的数相加得到的。

思路:

(1)Ulam数列的定义:U(n)表示Ulam数列中第n个元素的值,其中U(1)=1,U(2)=2,对于n>2,U(n)表示从前面的项中取出两个不同的数相加得到的最小的不能表示成其他项之和的数。

(2)由于Ulam数列中每一项的值都是通过前面的项中取出两个不同的数相加得到的,因此可以使用循环从3到n遍历每一项,并在每一轮循环中执行一次求解过程,找到第一个不能表示成其他项之和的数即为第n项的值。

以下是一份参考代码:

#include <stdio.h>

int ulam(int n)
{
    int a[n];
    a[0] = 1;
    a[1] = 2;
    for(int i = 2; i < n; i++)
    {
        int count = 0;
        for(int j = 0; j < i && count <= 2; j++)
        {
            for(int k = j+1; k < i && count <= 2; k++)
            {
                int sum = a[j] + a[k];
                int flag = 1;
                for(int l = 0; l < i; l++)
                {
                    if(sum == a[l] && l != j && l != k)
                    {
                        flag = 0;
                        break;
                    }
                }
                if(flag)
                {
                    a[i] = sum;
                    count++;
                }
            }
        }
    }
    return a[n-1];
}

int main()
{
    int n;
    printf("请输入一个正整数:\n");
    scanf("%d", &n);

    int res = ulam(n);
    printf("Ulam数列第%d项的值为%d\n", n, res);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值