C. p-binary(二进制暴力)
\(设最后的答案为t,那么有\)
\[2^{x_1}+2^{x_2}+...2^{x_t}+tp=n
\]
\(那我们完全可以枚举这个t,判断n-tp(我们下面记为z)能刚好被t个二进制表示\)
\(首先,z如果小于t,那一定无法表示,因为每一个二进制最小是2^0=1,t个二进制最小是t\)
\(然后,我们数一下z的二进制1的个数,假如t不够的话也不行。\)
\(为什么?因为二进制高位的1可以由低位的1补齐,所以t大了没事,但不能比z的二进制1个数少.\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll cha(ll s)
{
ll ans=0;
while(s)
{
if(s&1) ans++;
s>>=1;
}
return ans;
}
ll ans=1e18;
int main()
{
ll n,p;
cin>>n>>p;
for(long long i=1;;i++)
{
ll z=n-p*i;
//用i个2进制数凑成z可以吗?
//只要当z>=i,且z的二进制1位数不多于i
if(z>=i&&cha(z)<=i)
{
ans=min(ans,i);
break;
}
if(z<0) break;//继续下去也是小于0
}
if(ans==1e18) cout<<-1;
else cout<<ans;
}