P1036 [NOIP 2002 普及组] 选数
来源:洛谷 ★ 1000
本题活力0.31按难度、完成结果与训练证据估算
算法如山行则将至
题目描述
从n个整数中选k个相加,求和为素数的组合数目。
思考与重做
王梓豪的同题记录 · 1 条
- 王梓豪 · 2026-08-19本次记录最后更新 2026.8.19
完成结果:未记录
用dfs取数暴力
队友同题 · 1 人3 条记录
完成结果:独立完成自评已掌握
按照《深入浅出》,继续刷洛谷题单
完成结果:未记录
这道题是深入浅出上的例题,我一开始自己做只能想到DFS(见另一个记录),也能做,但是深入浅出给出的使用二进制的性质进行子集枚举,很有意思 核心思路:对于子集,二进制下的数的每一位可以视为是否取到,1表示取到,0表示不取 1. 交:两个集合的交集可以表示为A1 & A2,当且仅当a1与b1均为1时取到 2. 并:A1 A2 3. 补:异或表示,A1 ^ A2 4. 包含: bool 表达式, (A1 A2==A1)&&(A1&A2==A2) 5. 属于: A1 & (1 <<…
完成结果:未记录
TLE了两次,最后没办法了看题解,优化过程真是酣畅淋漓
代码
#include <bits/stdc++.h>
using namespace std;
vector<int> a;
int cnt=0;
bool isprime(int n)
{
if(n <= 1) return false;
for(int i=2;i*i <= n; i++)
{
if(n%i == 0) return false;
}
return true;
}
void dfs(int rest,int total,int curr)
{
if(rest==0)
{
if(isprime(total))
{
cnt++;
return ;
}
}
if((int)a.size()-curr<=rest)return;
for(int i=curr+1;i<a.size();i++)
{
dfs(rest-1,total+a[i],i);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,k,temp;
cin>>n>>k;
for(int i=0;i<n;i++)
{
cin>>temp;
a.emplace_back(temp);
}
dfs(k,0,-1);
cout<<cnt;
}