C语言入门算法——选数

题目描述:

已知 n 个整数 x1​,x2​,⋯,xn​,以及 1 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4个整数分别为3,7,12,19 时,可得全部的组合与它们的和为:

3+7+12=22

3+7+19=29

7+12+19=38

3+12+19=34

现在,要求你计算出和为素数共有多少种。

例如上例,只有一种的和为素数:3+7+19=29。

输入格式

第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)。

第二行 n 个整数,分别为 x1​,x2​,⋯,xn​(1≤xi​≤5×10^6)。

输出格式

输出一个整数,表示种类数。

输入输出样例

输入 #1

复制代码
4 3
3 7 12 19

输出 #1

复制代码
1

说明/提示

【题目来源】

P1036 NOIP2002 普及组 选数

思路及部分代码:

1. 判断素数

素数:只能被1和自己整除的数。

复制代码
int prime_number(long long int n){
    if(n == 2 || n == 1) return 1;
    for(long long int i = 2; i<=(n/2)+1; i++){
        if(n % i == 0) return 0;
    }
    return 1;
}

2. 递归函数

复制代码
void scan(int ni, int n, int k, long long int num){
    if(k <= 0){
        cnt = cnt + prime_number(num);
        return;
    }
    for(int i = ni;i < n;i++){
        scan(i+1,n,k-1,num + number[i]);
    }
    return;
}

总代码:

复制代码
#include <stdio.h>

long long int number[20] = {0};

int cnt = 0;

int prime_number(long long int n){
    if(n == 2 || n == 1) return 1;
    for(long long int i = 2; i<=(n/2)+1; i++){
        if(n % i == 0) return 0;
    }
    return 1;
}

void scan(int ni, int n, int k, long long int num){
    if(k <= 0){
        cnt = cnt + prime_number(num);
        return;
    }
    for(int i = ni;i < n;i++){
        scan(i+1,n,k-1,num + number[i]);
    }
    return;
}

int main (){
    int n,k;
    scanf("%d %d",&n, &k);

    for(int i=0;i < n; i ++){
        scanf("%lld",&number[i]);
    }

    scan(0,n,k,0);
    printf("%d",cnt);
    return 0;
}   

总结:

这段代码实现了一个递归函数 scan,用于计算一组数中满足特定条件的子集的数量。其中,函数 prime_number 用于判断一个数是否为质数。然后在 main 函数中读取输入,调用 scan 函数并输出结果。

不足之处:

  1. 缺少输入验证: 代码中没有对输入进行充分的验证,比如输入的 n 和 k 是否在合理范围内,以及是否满足特定条件。这可能导致程序在某些情况下出现错误。

  2. 全局变量的使用: 全局变量 cnt 和 number 可能会导致代码可读性和可维护性下降,尤其在大型程序中更容易引起混乱。

  3. 递归深度限制: 递归函数 scan 可能存在递归深度过深的风险,如果 n 过大或者 k 过大,可能导致栈溢出。

  4. 质数判断效率: 质数判断函数 prime_number 的效率可能不高,因为它遍历了大约一半的数来判断一个数是否为质数,可以考虑优化算法。

改进建议:

  1. 输入验证: 在读取输入时,应该验证输入的有效性,确保 n 和 k 符合要求,避免出现不必要的错误。

  2. 避免全局变量: 尽量避免使用全局变量,可以将 cnt 和 number 变量传递给函数,或者将它们定义在 main 函数内部。

  3. 优化递归: 考虑优化递归函数,避免出现过深的递归调用。可以尝试使用迭代或其他方法替代递归。

  4. 质数判断优化: 优化质数判断函数,可以只遍历到 sqrt(n) 范围内的数进行判断,减少不必要的计算。

  5. 代码注释和命名: 添加适当的注释来解释代码的功能和逻辑,同时使用更具描述性的变量和函数命名,提高代码的可读性。

  6. 错误处理: 在可能出现错误的地方添加适当的错误处理机制,以便程序在出现异常情况时能够正确处理。

相关推荐
怕浪猫4 小时前
GEO 优化到底是什么?AI时代内容创作者必须懂的新技能
算法·面试·github
朝朝辞暮i6 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
Evand J6 小时前
【MATLAB例程】三维RRT+APF避障路径规划与到达角(AOA)定位算法|三维路径优化与定位仿真例程
算法·matlab·路径规划·代码·定位·rrt·aoa
小师兄吃牛肉7 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记7 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
炸膛坦客7 小时前
单片机开发工具篇:(十四)配置输出 .map 文件及其本地路径
c语言·单片机·嵌入式硬件
言乐67 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
weixin_307779137 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
kakakahahahaha8 小时前
Windows C盘临时文件清理:%temp%、Windows Temp、Prefetch、Windows.old与hiberfil.sys处理指南
c语言·开发语言·windows
朝朝辞暮i8 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法