zoukankan      html  css  js  c++  java
  • Problem C: 【递归入门】组合+判断素数

    Description

    已知 n 个整数b1,b2,…,bn

    以及一个整数 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) 
    第二行n个整数:x1,x2,…,xn (1<=xi<=5000000) 

    Output

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

    Sample Input

    4 3
    3 7 12 19
    

    Sample Output

    1

    最终AC代码:

    #include <cstdio>
    int k, n, num, p[25], a[25]; //p[]数组保留选择的数组序号
    bool vis[22]={false};
    bool isPrime(int n){
        if(n < 2) return false;
        for(int i=2; i*i<=n; i++) if(n%i == 0) return false;
        return true;
    }
    void DFS(int index){
        if(index == k+1){
            int i, sum=0;
            for(i=1; i<=k; i++) sum += a[p[i]];
            if(isPrime(sum)) num++;
            return ;
        }
        for(int i=index; i<=n; i++){
            if(!vis[i] && p[index-1]<i){
                p[index] = i;
                vis[i] = true;
                DFS(index+1);
                vis[i] = false;
            }
        }
    }
    int main(){
        int i;
        p[0] = 0;
        while(~scanf("%d %d", &n, &k)){
            for(i=1; i<=n; i++) scanf("%d", &a[i]);
            num = 0;
            DFS(1);
            printf("%d
    ", num);
        }
        return 0;
    }

    总结:在最开始写代码时,担心大数据时会超时,所以采用map记录已经判断过的sum,但是后来测试发现,当sum一样,组成sum的元素不同时,这里视为两种情况。其次,当使用如下形式 int a=sqrt(b); 那么得到的a的值将为0 正确做法是 int a=(int)sqrt(b); 

    后来百度,看到一种更妙的解法(虽然我承认这个解法见过好多次,但是为什么每次自己想不起来呢?)

    【递归入门】组合+判断素数

    自己后来跟着这个思路写了一遍,如下:

    #include <cstdio>
    int n, k, num, a[25];
    bool isPrime(int n){
        if(n < 2) return false;
        for(int i=2; i*i<=n; i++) if(n%i == 0) return false;
        return true;
    }
    void DFS(int index, int cnt, int sum){
        if(cnt == k){ //说明得到了k个数 
            if(isPrime(sum))  num++;
            return ;
        }
        
        if(index==n || cnt>k) return ; //说明超过判断范围了
        
        DFS(index+1, cnt+1, sum+a[index]); //选择index
        
        DFS(index+1, cnt, sum); //不选择index 
    }
    int main(){
        int i;
        while(~scanf("%d %d", &n, &k)){
            for(i=0; i<n; i++) scanf("%d", &a[i]);
            num = 0;
            DFS(0, 0, 0);
            printf("%d
    ", num);
        }
        return 0;
    }

    嗯,很简单,而且速度快了很多.........

  • 相关阅读:
    hadoop生态--ElasticSearch--ES操作
    Haoop生态--ElasticSeaarch(1)--ES预备知识(全文检索的概念、Lucence、倒排索引)
    hadoop生态--Hive(2)--Hive的使用方式
    hadoop生态--Zookeeper
    gsoap使用
    set容器
    如何杀死defunct进程
    关于多态
    数组类型与函数指针基本语法知识
    syslog日志
  • 原文地址:https://www.cnblogs.com/heyour/p/12655518.html
Copyright © 2011-2022 走看看