(三进制枚举+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;
}