题目:集合A={1,2,3,5},从中任取几个数相加等于10,并打印各得哪几个数?
补充参照:http://www.cnblogs.com/tinaluo/p/5294341.html
上午弄明白了幂集的问题,不得不说这是一个极大的突破!只要把这个思路缕清楚了,就可以解很多问题。
幂集问题,简而言之就是穷举,只是方式有特色,取某个元素,然后又舍去某个元素,隐形的借用了二叉树的先序遍历。有了这个思路,再去解本题,就变的很容易。
按照幂集的思路,其实也就是穷举集合A的所有可能,并且求每个可能的和,如果等于10,就打印那几个元素。
第一个问题,如何舍?字符串和int数组有不同,字符串可以给某个元素赋值0就算舍去,然后打印字符串,而int数组,可以用sum-=a[i]的形式,也就是先让它加,回溯的时候再减去它,等于没加。这个问题解决了!
第二个问题,如何打印是哪几个数?如本题,可以看出是2+3+5=10,就必须跟综这几个数。于是,想到用一个标志flag数组,如果某个数被加上了,就在对应的flag标志数组中标识为1,一旦得到结果,那么flag数组就是:0 1 1 1这种情形。
而界限,这里还是采用幂集的方式,i>=n。思路一旦缕清楚,代码也随之而来!再次说明,理解一个知识是极其重要的!
【3/25号补充】假如有这种可能,只要找到一个结果就终止。这里可以设置一个监视哨flag,在函数的第一步就检测,如果不设置监视,则一直穷举...
void f(....)/*函数*/ { if(flag)/*监视标志*/ { ......./*整个函数体*/ } }
/*--------完整代码@映雪--2016/3/19-------*/ #include <iostream> using namespace std; int a[4]={1,2,3,5}; int flag[4]; void f(int a[],int i,int n,int sum) { if(i>=n) { if(sum==10)/*得到结果*/ { for(int j=0;j<4;j++) { if(flag[j]==1) { cout<<a[j]<<" "; } } cout<<endl; } } else { sum+=a[i]; flag[i]=1; f(a,i+1,n,sum); sum-=a[i]; flag[i]=0; f(a,i+1,n,sum); } } int main() { f(a,0,4,0); return 0; }