zoukankan      html  css  js  c++  java
  • DFS-简单递归

    【简单递归】

    题目描述

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

    输入

    第一行两个整数:n , k (1<=n<=20,k<n) 
    第二行n个整数:x1,x2,…,xn (1<=xi<=5000000)

    输出

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

    样例输入

    4 3
    3 7 12 19
    样例输出

    1

    代码

    #include <iostream>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    //判断是否是素数
    bool isprime(int n)
    {
        if (n<1)return false;
        for (int i=2;i*i<n;i++)
        {
            if (n%i==0)//n&(i-1)==0
                return false;
        }
        return true;
    }
    int a[22],p[22], b[22];
    bool vis[22];
    int n, k, sum, ans;
    int cnt = 0;
    vector<vector<int> > index_vec;
    vector<int> sum_vec;
    void dfs(int index)
    {
        cout << "Enter dfs, " << ++cnt << "th" << ", index:" << index << ", p[index-1]:" << p[index-1] << endl;
        if (index==k+1)
        {
            if (isprime(sum))
            {
                ans++;
                cout << "sum:" << sum << " is prime." << endl;
            }
    
            //打印每一个元素组合
            vector<int> v;
            for (int i=1;i<=index-1;i++)
            {
                cout << p[i] << " ";
                v.push_back(p[i]);
    
            }
            index_vec.push_back(v);
            sum_vec.push_back(sum);
            cout << endl;
            cout << "sum:" << sum << endl;
            return;
        }
    
        //遍历n个数
        for (int i=1;i<=n;i++)
        {
            //条件1:该元素在本次遍历中是否被访问过
            //条件2:保障遍历的i下标大于已统计过的最后一个元素下标
    
            cout << "i:" << i << ", vis:" << vis[i] << ", index:" << index << ", p[index-1]:" << p[index-1] << endl;
            if (vis[i]==false && i>p[index-1])
            {
                p[index] = i;//数组p用来保存元素下标,index为当前统计的元素总数目
                vis[i] = true;//标记该元素已被该次计算统计过
                sum += a[i];//更新和,在全排列过程中,对结果进行统计
    
                cout << "Enter the next dfs" << endl;
                cout << "sum:" << sum << ", i:" << i << ", vis[i]:" << vis[i] << endl;
    
                dfs(index+1);//开始下一次递归计算
    
                cout << "return from dfs" << endl;
    
                //回溯
                vis[i] = false;
                sum -= a[i];
    
                cout << "sum:" << sum << ", i:" << i << ", vis[i]:" << vis[i] << ", index:" << index << ", p[index-1]:" << p[index-1] << endl;
    
            }
        }
    }
    
    int main()
    {
        //初始化全局变量
        memset(b, 0, sizeof(b));
        memset(vis, false, sizeof(vis));
    
        //获取输入
        cin >> n >> k;
        cout << "n=" << n << " ,k=" << k << endl;
        for (int i=1; i<=n;i++)
        {
            cin >> a[i];
            p[i]=i;
        }
    
        ans = 0;
        dfs(1);
    
        cout << ans << endl;
        int seq=0;
        for (auto it: sum_vec)
        {
            cout << "sum: " << it << endl;
            for (auto it_idx: index_vec[seq])
            {
                cout << it_idx << " ";
            }
            cout << endl;
            ++seq;
        }
    
        return 0;
    }
    
    

    题目解析

    循环中调用递归

    代码打印帮助理解递归过程

    4
    3
    n=4 ,k=3
    3
    7
    12
    19
    
    Enter dfs, 1th, index:1, p[index-1]:0
    i:1, vis:0, index:1, p[index-1]:0
    Enter the next dfs
    sum:3, i:1, vis[i]:1
    Enter dfs, 2th, index:2, p[index-1]:1
    i:1, vis:1, index:2, p[index-1]:1
    i:2, vis:0, index:2, p[index-1]:1
    Enter the next dfs
    sum:10, i:2, vis[i]:1
    Enter dfs, 3th, index:3, p[index-1]:2
    i:1, vis:1, index:3, p[index-1]:2
    i:2, vis:1, index:3, p[index-1]:2
    i:3, vis:0, index:3, p[index-1]:2
    Enter the next dfs
    sum:22, i:3, vis[i]:1
    Enter dfs, 4th, index:4, p[index-1]:3
    1 2 3 
    sum:22
    return from dfs
    sum:10, i:3, vis[i]:0, index:3, p[index-1]:2
    i:4, vis:0, index:3, p[index-1]:2
    Enter the next dfs
    sum:29, i:4, vis[i]:1
    Enter dfs, 5th, index:4, p[index-1]:4
    sum:29 is prime.
    1 2 4 
    sum:29
    return from dfs
    sum:10, i:4, vis[i]:0, index:3, p[index-1]:2
    return from dfs
    sum:3, i:2, vis[i]:0, index:2, p[index-1]:1
    i:3, vis:0, index:2, p[index-1]:1
    Enter the next dfs
    sum:15, i:3, vis[i]:1
    Enter dfs, 6th, index:3, p[index-1]:3
    i:1, vis:1, index:3, p[index-1]:3
    i:2, vis:0, index:3, p[index-1]:3
    i:3, vis:1, index:3, p[index-1]:3
    i:4, vis:0, index:3, p[index-1]:3
    Enter the next dfs
    sum:34, i:4, vis[i]:1
    Enter dfs, 7th, index:4, p[index-1]:4
    1 3 4 
    sum:34
    return from dfs
    sum:15, i:4, vis[i]:0, index:3, p[index-1]:3
    return from dfs
    sum:3, i:3, vis[i]:0, index:2, p[index-1]:1
    i:4, vis:0, index:2, p[index-1]:1
    Enter the next dfs
    sum:22, i:4, vis[i]:1
    Enter dfs, 8th, index:3, p[index-1]:4
    i:1, vis:1, index:3, p[index-1]:4
    i:2, vis:0, index:3, p[index-1]:4
    i:3, vis:0, index:3, p[index-1]:4
    i:4, vis:1, index:3, p[index-1]:4
    return from dfs
    sum:3, i:4, vis[i]:0, index:2, p[index-1]:1
    return from dfs
    sum:0, i:1, vis[i]:0, index:1, p[index-1]:0
    i:2, vis:0, index:1, p[index-1]:0
    Enter the next dfs
    sum:7, i:2, vis[i]:1
    Enter dfs, 9th, index:2, p[index-1]:2
    i:1, vis:0, index:2, p[index-1]:2
    i:2, vis:1, index:2, p[index-1]:2
    i:3, vis:0, index:2, p[index-1]:2
    Enter the next dfs
    sum:19, i:3, vis[i]:1
    Enter dfs, 10th, index:3, p[index-1]:3
    i:1, vis:0, index:3, p[index-1]:3
    i:2, vis:1, index:3, p[index-1]:3
    i:3, vis:1, index:3, p[index-1]:3
    i:4, vis:0, index:3, p[index-1]:3
    Enter the next dfs
    sum:38, i:4, vis[i]:1
    Enter dfs, 11th, index:4, p[index-1]:4
    2 3 4 
    sum:38
    return from dfs
    sum:19, i:4, vis[i]:0, index:3, p[index-1]:3
    return from dfs
    sum:7, i:3, vis[i]:0, index:2, p[index-1]:2
    i:4, vis:0, index:2, p[index-1]:2
    Enter the next dfs
    sum:26, i:4, vis[i]:1
    Enter dfs, 12th, index:3, p[index-1]:4
    i:1, vis:0, index:3, p[index-1]:4
    i:2, vis:1, index:3, p[index-1]:4
    i:3, vis:0, index:3, p[index-1]:4
    i:4, vis:1, index:3, p[index-1]:4
    return from dfs
    sum:7, i:4, vis[i]:0, index:2, p[index-1]:2
    return from dfs
    sum:0, i:2, vis[i]:0, index:1, p[index-1]:0
    i:3, vis:0, index:1, p[index-1]:0
    Enter the next dfs
    sum:12, i:3, vis[i]:1
    Enter dfs, 13th, index:2, p[index-1]:3
    i:1, vis:0, index:2, p[index-1]:3
    i:2, vis:0, index:2, p[index-1]:3
    i:3, vis:1, index:2, p[index-1]:3
    i:4, vis:0, index:2, p[index-1]:3
    Enter the next dfs
    sum:31, i:4, vis[i]:1
    Enter dfs, 14th, index:3, p[index-1]:4
    i:1, vis:0, index:3, p[index-1]:4
    i:2, vis:0, index:3, p[index-1]:4
    i:3, vis:1, index:3, p[index-1]:4
    i:4, vis:1, index:3, p[index-1]:4
    return from dfs
    sum:12, i:4, vis[i]:0, index:2, p[index-1]:3
    return from dfs
    sum:0, i:3, vis[i]:0, index:1, p[index-1]:0
    i:4, vis:0, index:1, p[index-1]:0
    Enter the next dfs
    sum:19, i:4, vis[i]:1
    Enter dfs, 15th, index:2, p[index-1]:4
    i:1, vis:0, index:2, p[index-1]:4
    i:2, vis:0, index:2, p[index-1]:4
    i:3, vis:0, index:2, p[index-1]:4
    i:4, vis:1, index:2, p[index-1]:4
    return from dfs
    sum:0, i:4, vis[i]:0, index:1, p[index-1]:0
    1
    sum: 22
    1 2 3 
    sum: 29
    1 2 4 
    sum: 34
    1 3 4 
    sum: 38
    2 3 4 
    
    Process finished with exit code 0
    
  • 相关阅读:
    spring3.2以后的cglib的jar包问题
    maven入门程序(二)
    maven安装配置(myeclipse)(一)
    spring中得到servletContext对象方法
    ftp上传java代码
    FileZilla ftp服务器安装
    spring junit参数
    说一说Servlet的生命周期?
    Servlet API中forward()与redirect()的区别?
    request.getAttribute()和 request.getParameter()有何区别?
  • 原文地址:https://www.cnblogs.com/studyofadeerlet/p/11407522.html
Copyright © 2011-2022 走看看