Codeforces Round #596 C

题意

对于 p p ,你拥有的数是 2 x + p 2^x +p
请利用最小数量的数组成 n n

题解

首先我们可以简单判断出这个数量不会超过30000
首先 n 1 e 9 n \leq 1e9 ,所以 2 x k 2^x*k 不会超过 1 e 9 1e9 ,当 x x 较大, k k
会保持不超过 1 e 5 1e5 ,当 x x 较小,较小的部分可以由较大的部分代替( 2 2 倍)
所以是远远不会超过 3 e 5 3e5

同时我们枚举这个数量,从而得到 n i p n-i*p

我们进行二进制分解,得到几个数,但是数量可能与我们枚举的数量不相等。
那怎么办呢
首先。一个 2 x 2^x 肯定等于 2 x 2^x 2 0 2^0 ,并且我们每把一个 1 1 往下调整一位就会多出两个,减去去掉的一个,就是每次都是一个一个往上加的,也就是说:如果一开始位数较少,但是总数量比枚举的大,就是可以达到的。

#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define sf(x) scanf("%d",&x)
using namespace std;
 
typedef long long ll;
const int maxn = 300000;
const ll mod = 1e9+7;
 
int n,p;
int num[maxn+100],a[maxn+100];
map<ll,int>mp;
 
int main(){
    cin>>n>>p;
    FOR(i,1,maxn){
        int m=n-i*p,tmp=m;
        if(m<0)break;
        int num=0;
        while(m){
            if(m%2)num++;
            m/=2;
        }
        if(num<=i&&i<=tmp){
            cout<<i<<endl;
            return 0;
        }
    }
    puts("-1");
}
发布了203 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/mxYlulu/article/details/104072279