题目描述
输入格式
输出格式
输出一个整数,表示种类数。
输入输出样例
输入 #1
4 3 3 7 12 19
输出 #1
1
3 2 1 开始
解析
它实现是从给定的一个整数序列中选择 k 个不同的数相加,使得它们的和为质数,并统计所有这样的组合
共有多少种。
为了实现这个功能,程序定义了两个主要函数:`isprime` 和 `dfs`
- `isprime` 函数用于检测一个正整数是否为质数。其工作原理是遍历从 2 到 sqrt(num) 的所有整数
检查 num 是否可以被这些数中的任何一个整除。如果 num 能被其中任何数整除,则该函数返回 0 表示 num
不是质数;否则,当循环结束后返回 1 表示 num 是质数
- `dfs` 函数是一个深度优先搜索算法,用于递归地生成所有可能的 k 个数的组合,并计算这些数的和
在每次递归调用中,它都会增加当前组合中的数的数量(step),并将当前数加入到总和(sum)中
当 step 达到 k+1 时,说明已经找到了一组包含 k 个数的组合
此时会使用 `isprime` 函数来判断这组数的和是否为质数
如果是质数,则将全局变量 ans 增加 1,表示找到了一种符合条件的组合
然后,通过改变下一次递归调用的参数,`dfs` 函数会尝试添加序列中下一个不同的数
直到穷举完所有的可能组合(⭐️)
主函数 `main` 首先读取输入数据:整数序列的长度 n 以及需要选择的数的数量 k。
接着,读取整个整数序列并存储在数组 x 中。然后,调用 `dfs` 函数开始搜索所有可能的组合。
最后输出 ans 变量的值,即满足条件的组合总数。
哇,真神奇,上代码
#include<bits/stdc++.h>
using namespace std;
int n,x[25],k,ans=0;
int isprime(int num){
for(int j=2;j*j<=num;j++){
if(num%j==0){
return 0;
}
}
return 1;
}
void dfs(int step,int f,int sum){
if(step==k+1){
if(isprime(sum)==1){
ans++;
}
return;
}
for(int i=f+1;i<=n;i++){
dfs(step+1,i,sum+x[i]);
}
}
int main(){
int i,j;
cin>>n>>k;
for(i=1;i<=n;i++){
cin>>x[i];
}
dfs(1,0,0);
cout<<ans;
return 0;
}
1 2 3 分析
它实现的功能是:给定一个整数序列和一个正整数`k`,
找出所有由`k`个元素组成的子集,使得这些子集的和为质数,
并统计这样的子集共有多少个。
- 函数`int isprime(int num)`:判断一个数是否为质数。它通过试除法来判断,如果该数可以被小于或等于其平方根的任何数整除,则不是质数,返回0;否则是质数,返回1。
- 函数`void dfs(int step,int f,int sum)`:
这是一个深度优先搜索(DFS)函数,
用于递归地生成所有可能的子集组合,
并检查它们的和是否为质数。
参数`step`表示当前生成到第几个数,
`f`表示下一个数的起始位置,`sum`表示当前子集的和。
- `int main()`:主函数,首先读入序列长度`n`和子集大小`k`,接着读入整个序列,然后调用`dfs`函数开始搜索,并输出满足条件的子集总数。
总的来说,这段程序使用了回溯算法来枚举所有可能的子集组合,并利用`isprime`函数检查每个组合的和是否为质数,从而统计出符合条件的子集数量。
CCF要来了,加加油!!
🥹
the end 新手上路悠~~~~~~~~~~~~