~$ 存档

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

题目:集合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;
}

 

posted on 2016-03-19 16:03  LuoTian  阅读(298)  评论(0编辑  收藏  举报