[蓝蓝计算机考研算法训练二期]-day19

162 阅读2分钟

26、完全数,又称完美数或完备数,是一些特殊的自然数。

它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。

例如:28,它有约数1、2、4、7、14、28,除去它本身28以外,其余5个数相加,1+2+4+7+14=28.

输入n,请输出n以内(含n)完全数的个数。

数据范围:1 <= n < 5*105

输入描述:

输入一个数字n

输出

输出不超过n的完全数的个数

示例1

输入:

1000

输出:

3

思路

本算法利用了欧拉算法,在这个代码中,我们首先定义了一个is_prime函数来判断一个数是否为质数。然后在主函数中,对于每个数i,计算i-1是否为素数或者为2、3、5的倍数,如果不是,则继续循环下一个数;否则,计算2^k-1是否为素数,如果是,则将完全数的个数count加1。最后输出在n以内共有多少个完全数。

具体实现

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

int is_prime(int n)
{
    int i;
    if (n < 2) {
        return 0;
    }
    for (i = 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}

int main()
{
    int n, i, j, k, count = 0;
    printf("请输入一个正整数n:");
    scanf("%d", &n);

    for (i = 2; i <= n; i++) {
        k = i - 1;
        if ((k % 2 == 0 || k % 3 == 0 || k % 5 == 0) && !is_prime(k)) {
            continue;
        }
        j = (1 << k) - 1;
        if (is_prime(j)) {
            count++;
        }
    }

    printf("在%d以内共有%d个完全数。\n", n, count);

    return 0;
}

27、输入一棵二叉树,求该树的深度。

从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度,根节点的深度视为1.

数据范围:节点的数量满足0 <= n <= 100,节点的值满足 0 <= val <= 100

进阶:空间复杂度O(1),时间复杂度O(n)

计入输入的用例为{1,2,3,4,5,#,6,#,#,7},那么如下图:

image.png

示例1

输入:

{1,2,3,4,5,#,6,#,#,7}

返回值:

4

示例2

输入:

{}

返回值:

0

思路

本算法的思路在于,首先,要先得到输入的值,即如何将题中给定的形式得到数字,题中进行了转换,并且,按照形式递归构造二叉树,再将数进行遍历得到树高。

具体实现

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

#define MAX_LEN 202

// 定义二叉树结构体
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};


// 创建新的节点
TreeNode* create_node(int val) {
    TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
    node->val = val;
    node->left = NULL;
    node->right = NULL;
    return node;
}

TreeNode* create_tree(int arr[], int size, int index) {
    // 如果当前的下标超过了数组的大小,那么返回NULL
    if (index >= size) {
        return NULL;
    }

    // 创建当前节点
    TreeNode* node = create_node(arr[index]);

    // 递归构建左右子树
    node->left = create_tree(arr, size, 2 * index + 1);
    node->right = create_tree(arr, size, 2 * index + 2);

    return node;
}

// 创建二叉树
struct TreeNode* createTree() {
    struct TreeNode *root = NULL;
    char str[MAX_LEN];
    int num[MAX_LEN];
    int n,i,j=0;
    
    // 将输入的内容按照字符串读入 
	scanf("%s", str);
	// 读取字符串中不含‘{’‘}’的内容 
	for (i = 0; str[i] != '}'; i++) {
        if (str[i] != '{') {
            str[j++] = str[i];
        }
    }
    
    str[j] = '\0';  // 确保新字符串以 '\0' 结尾
    
	// 分割字符串并转换为数字
	i=0;
    char *token = strtok(str, ",");
    while (token != NULL) {
        num[i++] = atoi(token);
        token = strtok(NULL, ",");
    }
    
    root = create_tree(num, i, 0);
    
    return root;
}

// 递归计算二叉树高度
int treeHeight(struct TreeNode *root) {
    if (root == NULL) {
        return 0;
    } else {
        int left_height = treeHeight(root->left);
        int right_height = treeHeight(root->right);
        return (left_height > right_height ? left_height : right_height) + 1;
    }
}

int main() {
    // 创建二叉树
    struct TreeNode *root = createTree();

    // 计算二叉树高度
    int height = treeHeight(root);

    // 输出二叉树高度
    printf("二叉树高度为:%d\n", height);

    return 0;
}

image.png

小结

今天的算法很有难度,差点就放弃了。