题解:P1036 [NOIP 2002 普及组] 选数
题解:P1036 [NOIP 2002 普及组] 选数
博客同步链接:https://china-fan.github.io/2025/02/26/LGP1036TJ.html。
思路
由于数据小,考虑暴力搜索每种可能并判断总和是否为素数。
详细一点(定义
- 确定当前选择的数;
- 从
x 遍历i 至整个数组a ,每次搜索dfs(m + 1, s + a_i, i + 1) ; - 当
m = k 了,判断s 是否为素数:- 是:
ans + 1 ; - 不是:结束搜索,因为后面没有继续搜索的必要。
- 是:
代码
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
long long n, k, ans, a[25];
bool check(long long x) // 判断 x 是否为质数
{
for (long long i = 2; i * i <= x; i++) // 避免使用 sqrt() 函数,减少精度误差
{
if (x % i == 0) // 等同于 x % i == 0
return false;
}
return true;
}
void dfs(long long m, long long s, long long x) // m:选的数个数,s:当前的和,x:下一个选的数的位置
{
if (m == k)
{
if (check(s)) // 如果当前的和是质数,则 ans++
ans++;
return;
}
for (long long i = x; i < n; i++) // 从 x 开始
dfs(m + 1, s + a[i], i + 1);
return;
}
int main()
{
cin >> n >> k;
for (long long i = 0; i < n; i++)
cin >> a[i];
dfs(0, 0, 0); // 初始状态:选的数个数为 0,当前的和为 0,下一个选的数的位置为 0
cout << ans << endl;
return 0;
}