【递归入门】
题目描述
已知 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