码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 1247C

时间:2019-10-27 17:02:18      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:while   print   names   class   答案   出现   bsp   scanf   force   

                传送门:https://codeforces.com/contest/1247/problem/C

   题意::给你一个 n 和 p,有这样的一种二级制  “p-binary” ( 2^x+p ,  x非负 ); 要你用最少数量的  “p-binary”之和表示  n;无法构成输出-1;

  数据大小: 1<=n<=1e9;-100<=p<=100;

  分析::  

因为 1e9<=2^31,所以我们只需枚举  i ( 1<=i<=31 )即可,根据题意推出变形后的等式   n-i*p == Σ (2^k) ;

假设 组成 n 的数出现重复了,重复数必然可以一个更大的来代替,所以枚举的 i 指的是出现的种数(当拆成更小的数时其数量必然增加,一定符合要求),这样也最小化了答案 只要保证 n-i*p 转化成 2^k之和 所需的最小数量<=i 即可;

 1 #include<bits/stdc++.h>
 2 #define ull unsigned long long
 3 #define ll long long
 4 const int inf=1e9+7;
 5 const int maxn=1e6+5;
 6 using namespace std;
 7 
 8 bool check(ll x,ll y)
 9 {
10     if(x<=0)
11         return 0;
12     ll ans=x,t=0;
13     while(ans)//求最小的组合数量
14     {
15         if(ans&1)
16             t++;
17         ans/=2;
18     }
19     return y>=t&&x>=y;// x>=y 因为2^k是大于等于1,x至少要大于构成种数y(不然构成不了)
20 }
21 int main()
22 {
23     ll n,p,ans=-1;
24     scanf("%lld%lld",&n,&p);
25     for(int i=1;i<=31;i++)
26     {
27         if(check(n-i*p,i))
28         {
29             ans=i;
30             break;
31         }
32     }
33     printf("%lld\n",ans);
34     return 0;
35 }

 

codeforces 1247C

标签:while   print   names   class   答案   出现   bsp   scanf   force   

原文地址:https://www.cnblogs.com/sj-gank/p/11747718.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!