P1036 [NOIP2002 普及组] 选数
[NOIP2002 普及组] 选数
题目描述
已知
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:
输入格式
第一行两个空格隔开的整数
第二行
输出格式
输出一个整数,表示种类数。
样例 #1
样例输入 #1
4 3
3 7 12 19
样例输出 #1
1
提示
【题目来源】
NOIP 2002 普及组第二题
2.题解
2.1 子集枚举
思路
概念请参考子集枚举
难点集中在如何确定n个数中选取k个数的问题,这里将n个数的下标组成一个二进制数
通过函数__builtin_popcount(){注意该函数前面的下划线是两个,后面的下划线是一个!!!}可以判断一个二进制数有几位是1来判断是否满足选取了k个数。
至于范围选定就是从[0,11111...111]即可,如何快速获得n个1? (即 (1 << n) - 1, 可参考链接中的介绍)
代码
// 子集枚举
#include<bits/stdc++.h>
using namespace std;
bool isPrime(int num){
if (num <= 1) return false;
if (num <= 3) return true;
// 若num不是质数,num = a * b, a > sqrt(num),则必有 b < sqrt(num), 我们只要看能否找到这个b即可判断了
for(int i = 2; i <= sqrt(num); i++){
if(num % i == 0) return false;
}
return true;
}
int main(){
int n, k;
int ans = 0;
cin >> n >> k;
vector<int> arr(n);
for(int i = 0; i < n; i++){
scanf("%d", &arr[i]);
}
int U = 1 << n; // 得到全集,确定范围
for(int S = 0; S < U; S++){ //枚举所有子集[0,U)
int sum = 0;
if(__builtin_popcount(S) == k){
for(int i = 0; i < n; i++){
if(S & (1 << i)) sum += arr[i];
}
if (isPrime(sum)) ans++;
}
}
cout << ans;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了