Barbells(三进制枚举+set)

(三进制枚举+set)

 

推荐阅读原文:https://blog.csdn.net/Code92007/article/details/86772413

 

题意:哑铃,有n个重量的杆,m个重量的盘。当左右重量相等时算作哑铃,问有几种可能重量的哑铃。

 

思路:

三进制枚举,

第i位为1代表给左边加第i块铁片,为2代表给右边加该铁片,为0代表不加

这样所有的集合都被枚举到了,

set维护这个可能高达3的14次方*14的集合就阔以了

实际也不会那么多

但隐隐约约觉得拿vector搞出来之后去重会超时

 

代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn = 18;
typedef long long ll;

int a[maxn];
int b[maxn];
set <ll> ans;

ll qpow( ll a, ll n )
{
    ll re=1;
    while ( n ) {
        if ( n&1 ) {
            re *= a;
        }
        n >>= 1;
        a *= a;
    }
    return re;
}

int main()
{
    int n,m,i,j;
    int tot = 0;
    cin >> n >> m;
    for ( i=0; i<n; i++ ) {
        scanf("%d",&a[i]);
    }
    for ( i=0; i<m; i++ ) {
        scanf("%d",&b[i]);
    }
    int isp = qpow(3,m);
    long long sum1=0,sum2=0;
    for ( i=0; i<isp; i++ ) {
        sum1 = 0;
        sum2 = 0;
        j = i;
        int cnt = 0;
        while ( j>0 ) {
            int t = j%3;
            j /= 3;
            if ( t==1 ) {
                sum1 += b[cnt];
            }
            else if ( t==2 ) {
                sum2 += b[cnt];
            }
            cnt ++;
        }
        if ( sum1==sum2 ) {
            for ( j=0; j<n; j++ ) {
                long long x = a[j]+sum1*2;
                ans.insert(x);
            }
        }
    }

    for ( set<ll>::iterator it=ans.begin(); it!=ans.end(); it++ ) {
        cout << *it << endl;
    }

    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值