P1036 选数

做的第一道涉及算法的题

题目:

已知 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)。

分析

  • 使用深度优先算法,从四个数中选出三个数
  • 判断是否是素数
  • 统计数量,输出

  • 坑爹之处

    • 输入 3 2 1 1 1 居然结果是3 ! 明明是三个一样的素数好吗!!
    • 允许上面那种重复,居然不允许a+b b+a这样的重复
    • 写到这里我突然发现我是个智障
    • 我要回去重学语文了。。
    • QAQ

我的代码:

#include<iostream>

using namespace std;

int n,k,book[20],a[20],y=1,sushu[20];
int num[20],total=0,sum=0;

int is_prime(int shuzi){
    int sign=0;
    for(int i=2;i<shuzi;i++){
        if(shuzi %i ==0)    sign=1; 
    }
    if(sign==0) return 1;  
    else return 0;
} 


int dfs( int step){

    if(step==k+1){

        for(int i=1;i<=k;i++){

            sum+=num[a[i]];
        }
        if(is_prime(sum) ){

            total++;
        }
        sum=0;
        return 0;
    }


    for(int i=1;i<=n;i++){
        if(book[i]==0){
            a[step]=i;
            book[i]=1;
            dfs(step+1);
            book[i]=0;
        }

    }
    return 0;
}

int jiecheng(int num1){
    int sum=1;
    for(int i=1;i<=num1;i++){
        sum=sum*i;
    }
    return sum;
} 

int main()
{

    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>num[i];
    }

    dfs(1);
    total=total/(jiecheng(k));
    cout<<total<<endl;

}

总结:

  • 不熟练dfs,所以采用了先按123……列出排列顺序,再对应到相应的数组,多用了很多数组。。
  • 最后去重时候, 最开始只考虑了的题中所给输入输出 4选3 时,重复六次,但这个数字并不适用于其他情况。
  • 先插一个别人家的代码。。。↓↓↓
#include<cstdio>
int n,k,ans;
int a[22];
int is_prime(int n){
    if(n == 1 || n == 0)return 0;
    if(n == 2)return 1;
    for(int i = 2; i*i <= n; i++)
      if(n % i == 0)return 0;
    return 1;
}
void dfs(int pos,int pps,int sum){
    if(!pos) { ans +=is_prime(sum);return ;}
    for(pps; pps <= n; pps++)dfs(pos -1,pps +1, sum + a[pps]);
}
int main(){
    scanf("%d%d", &n,&k);
    for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
    dfs(k,1, 0);
    printf("%d\n", ans);
    return 0;
}
  • 首先,在判断素数时候,只需要计算到根号n即可。否则时间复杂度是指数倍。
  • 写法太简略,差评!

- 在dfs中,第一位从1开始循环,第二位从2开始循环,第三位从3开始循环……可以省出无数代码量!

  • 太困了 睡觉! 2017年5月7日02:23:33
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值