【洛谷 P1036】[NOIP2002 普及组] 选数 题解(深度优先搜索+判断质数+枚举子集)

简介: **NOIP2002普及组选数问题**:给定$n$个整数和一个整数$k$,需找出所有$k$个数的组合,计算它们的和为素数的种类数。输入包含$n$和$k$,以及$n$个整数;输出是符合条件的组合数。例如,对于输入`4 3`和数组`[3, 7, 12, 19]`,输出为`1`。代码使用递归枚举子集并检查质数的方法。

[NOIP2002 普及组] 选数

题目描述

已知 $n$ 个整数 $x_1,x_2,\cdots,x_n$,以及 $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 \le n \le 20$,$k<n$)。

第二行 $n$ 个整数,分别为 $x_1,x_2,\cdots,x_n$($1 \le x_i \le 5\times 10^6$)。

输出格式

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

样例 #1

样例输入 #1

4 3
3 7 12 19

样例输出 #1

1

提示

【题目来源】

NOIP 2002 普及组第二题

思路

通过搜索枚举子集,判断质数后计数。

AC代码

#include <iostream>
#include <cmath>
#define AUTHOR "HEX9CF"
using namespace std;

const int maxn = 100005;

int n, k;
int cnt = 0;
int a[maxn], b[maxn];

bool pn(int x)
{
   
    if (x <= 1)
    {
   
        return false;
    }
    for (int i = 2; i < sqrt(x); i++)
    {
   
        if (!(x % i))
        {
   
            return 0;
        }
    }
    return true;
}

void f(int x, int y)
{
   
    if (x == k)
    {
   
        int sum = 0;
        for (int i = 0; i < k; i++)
        {
   
            // cout << b[i] << " ";
            sum += b[i];
        }
        if (pn(sum))
        {
   
            cnt++;
        }
        // cout << endl;
        return;
    }
    for (int i = y + 1; i <= n; i++)
    {
   
            b[x] = a[i];
            f(x + 1, i);
    }
}

int main()
{
   
    b[0] = 0;
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
   
        cin >> a[i];
    }
    f(0, 0);
    cout << cnt << endl;
    return 0;
}
目录
相关文章
|
12天前
|
C++
【洛谷 P1307】[NOIP2011 普及组] 数字反转 题解(字符串)
**NOIP2011普及组题目:给定整数N,反转其位得到新数。新数首位非0(除非N=0)。输入0时直接输出0,其他情况输出反转后的数,考虑负数及前导0。提供的C++代码实现通过读入字符串,反转数字顺序并处理符号和前导0。**
10 0
|
12天前
【洛谷 P1307】[NOIP2011 普及组] 数字反转 题解(取余)
NOIP2011普及组试题,要求反转整数N的位得到新数,保持正负号和非零最高位。输入一个整数N,输出反转后的新数。样例输入1:123,输出:321;样例输入2:-380,输出:-83。代码使用取余法实现,处理负数时保留符号。
8 0
|
4天前
|
算法 测试技术 程序员
力扣经典150题第二十七题:两数之和 II - 输入有序数组
力扣经典150题第二十七题:两数之和 II - 输入有序数组
6 1
|
12天前
|
C++
【洛谷 P1044】[NOIP2003 普及组] 栈 题解(递归+记忆化搜索)
**NOIP2003普及组栈问题**:给定操作数序列1到n,仅允许push(进栈)和pop(出栈)操作。目标是计算所有可能的输出序列总数。输入包含一个整数n(1≤n≤18)。示例输入3,输出5。当队列空时返回1,栈空则只能入栈,栈非空时可入栈或出栈。AC C++代码利用记忆化搜索求解。
11 1
|
12天前
|
C++
【洛谷 P1075】[NOIP2012 普及组] 质因数分解 题解(判断质数)
NOIP2012普及组题目,给定合数$n$由两个不同质数乘积组成,求较大质数。输入一个正整数$n$,输出较大质因子。例如输入21,输出7。代码使用C++,通过循环和质数判断找到能整除$n$的质数,再求另一个质数,并输出较大者。
7 0
|
12天前
|
机器学习/深度学习 存储
【洛谷 P1028】[NOIP2001 普及组] 数的计算 题解(递归)
**NOIP2001普及组数的计算**:给定自然数\( n \),构造数列,新数不超过序列最后一项一半。求合法数列个数。输入\( n \)(\(1 \leq n \leq 10^3\))。样例:输入6,输出6。递归解决,代码中定义函数`f`实现递归计算,总和存储在`cnt`中,最后输出。
8 0
|
12天前
|
机器学习/深度学习 人工智能
【洛谷 P1028】[NOIP2001 普及组] 数的计算 题解(递推)
在NOIP2001普及组的数的计算题目中,给定自然数`n`,需构造遵循特定规则的合法数列。合法序列始于`n`,新元素不超过前一项的一半。任务是找出所有这样的数列数量。例如,当`n=6`时,合法序列包括`6`, `6,1`, `6,2`, `6,3`, `6,2,1`, `6,3,1`。程序通过动态规划求解,当`i`为奇数时,`a[i] = a[i - 1]`;为偶数时,`a[i] = a[i - 1] + a[i / 2]`。代码中预处理数组`a`并输出`a[n]`作为答案。输入`n`后,程序直接计算并打印合法数列个数。
15 0
|
12天前
【洛谷 P1035】[NOIP2002 普及组] 级数求和 题解(循环)
**NOIP2002普及组题目:求级数$S_n=1+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n}$超过$k$的最小$n$。给定$1\leq k\leq 15$,输出满足$S_n&gt;k$的$n$。输入$1$个整数$k$,输出相应$n$。例如,输入$1$,输出$2$。代码中使用double确保精度,通过累加求和判断条件找到$n$。**
8 0
|
12天前
|
存储
【洛谷 P2141】[NOIP2014 普及组] 珠心算测验 题解(集合+多重循环)
**NOIP2014普及组的珠心算测验题要求参赛者找出给定集合中多少个数可表示为其他两个不同数的和。输入含n个正整数,输出满足条件的数的个数。样例输入4个数,输出2,因1+2=3且1+3=4。代码利用集合存储和,遍历所有数对组合,当找到匹配和时插入集合,最后输出集合大小。注意数据规模为n≤100,数不超过10,000。**
14 0
|
12天前
【洛谷 P1088】[NOIP2004 普及组] 火星人 题解(全排列+向量)
**火星人问题摘要:** NOIP2004普及组竞赛中的题目,涉及火星人用手指的排列表示数字。人类需计算火星人数字与给定数值之和的新排列。给定火星人手指数N(≤10000),加上的数M(≤100),以及初始排列,要求输出新排列。30%的数据中N≤15,60%的数据中N≤50。使用`next_permutation`函数找到第M个排列。样例:N=5, M=3, 初始排列1 2 3 4 5,输出1 2 4 5 3。
7 0