zoukankan      html  css  js  c++  java
  • 洛谷P1036.选数(DFS)

    题目描述

    已知 n个整数 x1,x2,…,xn,以及11个整数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≤n≤20,k<n)
    x1,x2,…,xn (1<=xi ≤5000000)

    输出格式

    屏幕输出,格式为: 11个整数(满足条件的种数)。

    输入输出样例

    输入

    4 3
    3 7 12 19

    输出

    1
     
     

    我的分析

     根据本蒟蒻的经验,凡是遇到类似排列组合的多种可能的穷举问题,基本上都可以用暴力搜索解决。此题也不例外。不过要注意,本题先要求出由k个数构成的所有可能组合(无重复),而不是由k个数构成的所有可能排列,故与数选取的顺序无关,在进行深度优先搜索的时候,一定要注意避免重复哦(´・ω・`)

      最后,本题滴参考代码如下:

    #include<iostream>
    #include<vector>
    #include<numeric>
    #include<algorithm>
    using namespace std;
    int n,k;
    vector<int> group; //用于缓存k个数的一种组合
    vector<vector<int>> groups;//保存多种组合
    //质数判断函数啦,这里就不多解释了
    bool isprime(int num){
        if(num<=1) return 0;
        for(int i=2;i<num/2;++i){
            if(num%i==0) return 0;
        }
        return 1;
    }
    //深度优先搜索递归调用函数,index为本轮调用函数所新加入的数的下标
    void dfs(int a[],int index){
        group.push_back(a[index]);//将该数加入缓存
        if(group.size()==k){
        //若缓存中的数达k个,则将该种缓存组合保存
            groups.push_back(group); 
            return;
        }
        //在该数加入缓存后,在该数右边继续依次搜寻下一个加入缓存的数
        for(int i=index+1;i<n;++i){ 
            dfs(a,i);
            group.pop_back();//在进行完一次深搜后缓存也一定要记得跟着“退栈”
        }
    }
    int main(){
        cin>>n>>k;
        int a[n];
        for(int i=0;i<n;++i){
            cin>>a[i];
        }
        //因为是组合数,故为了不重复,我们定义如下规则:
        //按下标顺序从左到右依次遍历所有数,每次遍历到一个数后,讲其加入缓存,
        //然后一定要在该数右边继续搜寻下一个加入缓存的数
        //这样可以做到不重不漏
        for(int i=0;i<n;++i){
            dfs(a,i);
            group.pop_back();
        }
        //计算所得的多个数组中和为质数的数组有多少个
        int count=0;
        for(int i=0;i<groups.size();++i){
            int sum=accumulate(groups[i].begin(),groups[i].end(),0);
            if(isprime(sum)) count++;
        }
        cout<<count<<endl;
        return 0;
    }
    
  • 相关阅读:
    桌面快捷方式图标问题的修复
    Visual Studio 2015简体中文版
    开源资源记录
    如何在InstallShield的MSI工程中调用Merge Module的Custom Action
    使用Open Live Writer写博客
    使用Window Media Player网页播放器
    Nginx日志常用统计分析命令
    Jetty 开发指南:嵌入式开发示例
    Jetty 开发指南: 嵌入式开发之HelloWorld
    使用Semaphore控制对资源的多个副本的并发访问
  • 原文地址:https://www.cnblogs.com/lonelyprince7/p/12247407.html
Copyright © 2011-2022 走看看