蓝桥杯练习034
部分和
题目描述
给定整数序列a1,a2,…,an,判断是否可以从中选出若干数,使它们的和恰好为k.
1≤n≤20
-10^8≤ai≤10^8
-10^8≤k≤10^8
样例:
输入
4
1 2 4 7
13
输出:
Yes (13=2+4+7)
解题思路
1.通过对输入数据的取与不取来凑k
2.对每一个位置上的元素都可以取或者不取
3.可以先考虑取第一个位置的元素,此时剩余k-a[0]还需要从剩余元素中取
4.然后考虑下一个位置
5.当k小于0或者数组下标越界时要返回上一次的位置
6.当k恰好为0时说明已经找到了满足的方式,根据要求输出结果
7.需要注意的是:不选cur位置元素的时候,dfs后要将该元素加入vec中
便于下次搜索要这个元素的情况
8.最后要回溯。将加入的元素删除
代码
#include<iostream>
#include<vector>
#include<cstdlib>
using namespace std;
int kk;
void dfs(int a[],int n,int k,int cur,vector<int> v){
if(k==0){//找到满足的值
cout<<"Yes("<<kk<<"=";
int size=v.size();
for(int i=0;i<size;i++)
cout<<v[i]<<(i==size-1?"":"+");
cout<<")"<<endl;
exit(0);//退出程序
}
//k小于0或cur和n相等,没有找到
if(k<0||cur==n)return;
dfs(a,n,k,cur+1,v);//不要cur这个元素
v.push_back(a[cur]);//将cur位置的元素加入v中
dfs(a,n,k-a[cur],cur+1,v);//要cur这个元素
v.pop_back(); //回溯
}
int main()
{
int n,k;
cin>>n;
int a[n];
vector<int> vec;
for(int i=0;i<n;i++)
cin>>a[i];
cin>>k;
kk=k;//保存k的值,便于输出状态
dfs(a,n,k,0,vec);
return 0;
}