【递归入门】

题目描述

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

版权声明:本文为studyofadeerlet原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/studyofadeerlet/p/11407522.html