牛客算法题--幸运的袋子--C++

思路:这道题就是找数组中的子集 ,乍一看没有思路,这道题可以用树的结构画图,用递归思想解决这道题。

这里有一个条件,如果想要和大于积,组合的数里面必须有一个数字1,这样才会存在和大于积,但不一定每个都是。我们要对这个数组排序,这样才能更好的组合。

那么在组合的过程中,遇到不是幸运的组合,需要将它跳过,跟下一个数进行组合,因为已经和这个不是幸运数字组合的数加或乘了,所以要将他回溯,把它减或除到上一个数的组合,这样才能跳过这个数,与下一个数重新组合。比如112356这个数组,当1 1 2 3和5组合不是幸运组合,因为我们已经将5这个数加和乘了,所以要回溯,减和除,将它变为1123再与6组合。

这之中很有可能出现重复的组合,需要去重。

#include <iostream>
#include <vector>
#include <algorithm>//sort头文件
using namespace std;

int GetLuckyPacket(vector<int>& x,int n,int pos,int sum,int multi)
{
    int count=0;
    for(int i=pos;i<n;i++)
    {
        sum+=x[i];
        multi*=x[i];
        if(sum>multi)
            count+=1+GetLuckyPacket(x,n,i+1,sum,multi);//继续加/乘第i+1位置的数    
        else if(x[i]==1)//因为组合中必须有1,所以遇到1,不用count+1,直接递归加或乘i+1位置的数
            count+=GetLuckyPacket(x,n,i+1,sum,multi);
        else
            break;//如果上面两个条件都不成立,直接跳出循环语句

        //回溯,走到这里要么是上面两个条件不成立,幸运组合不成立;要么就是走到循环最后了,需要返回递归的值
        sum-=x[i];
        multi/=x[i];

        //去重,上两个条件不成立(不是1,sum<multi),判断当前数字和此后的数字是不是重复的,因为此数字已经组不成幸运组合,那么它的重复数字都是无效的
        while(i<n-1 && x[i]==x[i+1])
        {
            i++;
        }
    }
    return count;
}

int main()
{
    int n;
    while(cin>>n)
    {
        vector<int> x(n);//初始化n个空间,初始值都是0,相当于vector<int> x(n,0);
        for(int i=0;i<n;++i)
        {
            cin>>x[i];
        }
        sort(x.begin(),x.end());//vector直接用迭代器,如果定义数组,直接用下标
        int count=GetLuckyPacket(x,n,0,0,1);//数组,个数,起始位置,加初始值,乘初始值
        cout<<count<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值