• NOIP 2002 选数


    洛谷 P1036 选数

    洛谷传送门

    JDOJ 1297: [NOIP2002]选数 T2

    JDOJ传送门

    Description

    ​ 已知 n 个整数 x1,x2,…,xn,以及一个整数 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。

    Input

    n , k (1< =n< =20,k<n) x1,x2,…,xn (1< =xi< =5000000 )

    Output

    一个整数(满足条件的种数)。

    Sample Input

    4 3 3 7 12 19

    Sample Output

    1

    题解:

    本题考查的知识点:递归生成全排列,质数判断。

    递归生成全排列的相关知识:

    相关知识—全排列传送门

    相关知识—质数判断传送门

    思路:

    我们要枚举(n)数中(k)个数的全排列之和有多少是质数,需要生成全排列再判断一下质数即可,如果依次枚举无疑会超时,所以我们想出递归深搜来优化这个问题:

    我们搜索的时候需要维护这么几个参数:首先是还剩多少个数没有选进去,然后是已经选进去的和是多少,最后是剩下数字的选取范围。

    所以我们有如下的递归思路:

    假如k==0,说明我们已经有了一个全排列,这时候需要判断,否则,就进入选取环节:从start到end枚举递归深搜,累加和。这样就得到了我们要求的答案。

    代码:

    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,k;
    int a[21];
    bool check(int x)
    {
        for(int i=2;i<=sqrt(x);i++)
            if(x%i==0)
                return 0;
        return 1;
    }
    int dfs(int k,int sum,int start,int end)
    {
        if(k==0)
            return check(sum);
        int tot=0;
        for(int i=start;i<=end;i++)
            tot+=dfs(k-1,sum+a[i],i+1,end);
        return tot;
    }
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        printf("%d",dfs(k,0,1,n));
        return 0;
    }
    
  • 相关阅读:
    第一个android开发,记录三
    第一个android开发,记录二
    第一个android开发,记录一
    第一行代码LitePal的问题
    第二阶段冲刺个人总结5
    PHP中验证码的制作教程
    选项卡的制作代码
    HTML5布局总结篇
    PHP实现简单的计算器
    PHP中的运算符
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11357604.html
Copyright © 2020-2023  润新知