【洛谷 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;
}
目录
相关文章
|
存储 算法 Java
【DFS(深度优先搜索)详解】看这一篇就够啦
本文介绍了深度优先搜索(DFS)算法及其应用。DFS从某个顶点出发,深入探索图的每条路径,直到无法前进为止,然后回溯。文章详细解释了DFS的基本思想,并通过示例图展示了其执行过程。此外,文中还探讨了三种枚举方式:指数型枚举、排列型枚举和组合型枚举,并提供了具体的代码实现。最后,文章通过几道练习题帮助读者更好地理解和应用DFS算法。
10011 19
【DFS(深度优先搜索)详解】看这一篇就够啦
|
搜索推荐 算法 C语言
冒泡排序:从小到大轻松搞定数组排序(c语言代码)
冒泡排序:从小到大轻松搞定数组排序(c语言代码)
430 0
【洛谷】P1308 [NOIP2011 普及组] 统计单词数
然后要被查找的b字符串,可能会出现第二个样例中的情况,也就是字符串a是to,而字符串b的Ottoman,这样是不符合题意的。为了 解决这个问题,我们将字符串a首尾都加一个空格,同时将字符串b首尾都加一个空格(这里是为了让字符串b的首单词和尾单词前后均有空格)为了能持续找字符串b中的所有字符串a,我们用一个while循环,如果能找到,就每次从能找到的位置的下一个位置(也就是能找到的位置下标+1)开始找,并及时更新位置,同时计数。因为不区分大小写,所以可以将两个字符串a,b都转为小写(也可以都转为大写)。
371 10
【洛谷】P1308 [NOIP2011 普及组] 统计单词数
|
人工智能 达摩院 算法
什么是优化技术?给算法小白同学的快速讲解和上手文
本文作者用一个曾经小白学习的视角,来讲解什么是优化问题,以及要如何用这个优化技术。
48421 59
|
算法 Java 数据安全/隐私保护
App逆向百例|12|某电商App Sign分析
App逆向百例|12|某电商App Sign分析
940 0
|
PHP 数据安全/隐私保护
virtual judge怎么改中文
若遗忘密码,可通过服务器的root权限重设,或直接联系您的服务器提供商获取支持。
231 0
|
人工智能 算法 C++
一篇带你速通前缀和算法(C/C++)
一篇带你速通前缀和算法(C/C++)
|
存储 安全 程序员
【洛谷 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。
229 0
|
Java 关系型数据库 MySQL
基于SpringBoot+Vue健身房管理系统(源码+部署说明+演示视频+源码介绍)(1)
基于SpringBoot+Vue健身房管理系统(源码+部署说明+演示视频+源码介绍)
421 1