D - Fill The Bag
[题目] http://codeforces.com/contest/1303/problem/D
题解:
二进制,位运算
把数拆开,从低位开始放,剩下的除2给更高一位
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<map>
#include<iomanip>
#define LL long long
#define INF 0x7fffffff/2
using namespace std;
LL lowbit(LL x)
{
return x&(-x);
}
int Get(int x)
{
return x==1?0:1+Get(x>>1);
}
int a[70];
int main()
{
int T,M;
LL N,x;
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
scanf("%lld%d",&N,&M);
int ans=0;
for(int i=1;i<=M;i++)
{
scanf("%lld",&x);
a[Get(x)]++;
}
for(int i=0;i<63&&N;i++)
{
if(a[i]==0)continue;
LL num=(1ll<<i);
if(num&N)
{
N-=num;
a[i]--;
}
if(a[i]&&lowbit(N)<num&&N)
{
LL tmp=lowbit(N);
while(tmp!=num)
{
num/=2;ans++;
if(N&num)N-=num;
}
a[i]--;
}
a[i+1]+=a[i]/2;
}
if(N)puts("-1");
else printf("%d\n",ans);
}
return 0;
}