• 【洛谷p1036】选数


    (一定要声明我太蒟了,这个题扣了一上午……)

    算法标签:

    ……


    dfs真的不是我所擅长的qwq,这道题的思路其实很简单,就是先dfs搜索所有可能的和,然后判断是不是质数。说着好说,然鹅并不好写:

    第一个想法是用线性筛把2—1e8之间的素数都筛出来,然后搜出一个ans后与质数表进行比较(因为毕竟感觉O(n)的快嘛)然后发现用线性筛预处理还不如直接O(根号n)的筛素数呢qwq,

    所以判断是否为素数部分:

    bool pan(int g){
        for(int i=2;i<=sqrt(g);i++)
          if(g%i==0) return 0;
        return 1;
    }

    接下来就是我学的滑天下之大稽的dfs了qwq:

    dfs里有三个量:1.记录每一次dfs代数和的sum;2.记录现在选中了几个数的cnt;3.现在选数选到的最后位置last(划重点);

    last的用途:

    用来保证不会出现既计算1(1)+5(3)又计算5(3)+1(1)的情况,其中(x)代表下标。last的使用方法:在dfs的for循环时,从last开始循环,到n停止,这样可以保证不会既计算1(1)+5(3)又计算5(3)+1(1)的情况(鬼知道怎么用的last)

    总之很神奇,复习一下dfs:

    1.常与递归同时使用;

    2.一般的dfs格式:

    int dfs(int k){
        if(满足最终条件){
           输出/储存……解;
           return 0;
        }
        for(int i=1;i<=某个条件;i++){
             if(满足条件){
                保存结果;
                dfs(下一个k);//这个k可以根据不同的题不同的解法;
                回溯;//把之前修改掉的值再改回来;
              }
         }
    }

    en--------

    题解:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int n,k,ans;
    int x[30];
    bool d[30];//判断是否已经被计算
    
    bool pan(int g){//判质数
        for(int i=2;i<=sqrt(g);i++)
          if(g%i==0) return 0;
        return 1;
    }
    
    int dfs(int sum,int c,int last){
        if(c==k) {//如果已经选择了k个数
            if(pan(sum))//判断它们的和是否为质数
                ans++;//如果是,ans++
            return 0;//返回上一层循环
        }
        for(int i=last;i<=n;i++){
            if(!d[i]) {//如果这个数还没有被算过
                d[i]=1;last++;//last++表示last之前的数已经被加过一遍了,不会被再加了
                dfs(sum+x[i],c+1,last);//dfs下一层
                d[i]=0;
            }
        }
        return 0;
    }
    
    int main(){
        
        scanf("%d%d",&n,&k);
        
        for(int i=1;i<=n;i++)
          scanf("%d",&x[i]);
        
        dfs(0,0,1);
        
        cout<<ans<<endl;
        
        return 0;
    }

    另外我要附上一段数据,不枉yky同学帮我存了一中午:

    100 5
    3 3 2 5 6 1 5 4 55 6 156 89 89 262 1115 5626 48 44 665 92 15 1152 62 95 4 8 11 526 59 8 46 49 26 55 2 55 4 6 54 962 11 56 655 66 898 226 1 5 41 5 56 26 4 44 668 9 454 6 21 415 1 2563 96 4 5223 2 65 1 51 8 65 2 65 3 56 126 33 256 89 415 1 6 3 558 9 11 55 66 88 9 1 2 6 66 645 46 56 5 89 64 56 4 546 4651 5646 463 45

  • 相关阅读:
    保留最大的数
    彩色宝石项链
    [leetcode] 403. Frog Jump
    [leetcode] 402. Remove K Digits
    Linux 更改时区、时间
    Linux系统时间同步方法
    mysql 5.7.28 地理位置计算详解
    springboot微服务项目集成为单体
    地理空间数据Geometry在MySQL中使用(一)
    mysql中geometry类型的简单使用
  • 原文地址:https://www.cnblogs.com/zhuier-xquan/p/10959037.html
Copyright © 2020-2023  润新知